3 回答
TA貢獻1744條經(jīng)驗 獲得超4個贊
這是我花了一些時間與自己斗爭的問題。有多種方法可以將子狀態(tài)保持在更高級別;但是,我發(fā)現(xiàn)在您的特定情況下,通常最好使用 Redux。
需要明確的是,我通常不惜一切代價避免 Redux(支持 React 的上下文),但 Redux 讓您能夠訂閱子組件中的特定狀態(tài)。當您只需要更新一個子組件時,偵聽子組件中的一個狀態(tài)將阻止您的父組件和兄弟組件更新。這在一次處理多個表單時效率更高。
例如,以下組件將僅偵聽影響其自身狀態(tài)的狀態(tài)更新。這些更新將繞過表單父組件和兄弟組件:
import React from 'react';
import { connect } from 'react-redux';
import * as actions from 'redux/actions';
// Custom component
import { InputField } from 'shared';
const FormOne = ({ me, actions }) => (
<form>
<InputField
inputId="f1f1"
label="field one"
value={me.fieldOne}
onChange={(e) => actions.setFormOneFieldOne(e.target.value)}
/>
<InputField
inputId="f1f2"
label="field two"
value={me.fieldTwo}
onChange={(e) => actions.setFormOneFieldTwo(e.target.value)}
/>
<InputField
inputId="f1f3"
label="field three"
value={me.fieldThree}
onChange={(e) => actions.setFormOneFieldThree(e.target.value)}
/>
</form>
);
export default connect(state => ({ me: state.formOne }), actions)(FormOne);
在上面的例子FormOne中只是監(jiān)聽自己的狀態(tài)更新;然而,使用上下文而不是 Redux 的類似邏輯將導致上下文提供者包裝的整個組件樹更新(包括父組件和兄弟組件):
import React, { useContext } from 'react';
// Custom component
import { InputField } from 'shared';
// Custom context - below component must be wrapped with the provider
import { FormContext } from 'context';
const FormTwo = () => {
const context = useContext(FormContext);
return(
<form>
<InputField
inputId="f2f1"
label="field one"
value={context.state.formTwo.fieldOne}
onChange={(e) => context.setFormTwoFieldOne(e.target.value)}
/>
<InputField
inputId="f2f2"
label="field two"
value={context.state.formTwo.fieldTwo}
onChange={(e) => context.setFormTwoFieldTwo(e.target.value)}
/>
<InputField
inputId="f2f3"
label="field three"
value={context.state.formTwo.fieldThree}
onChange={(e) => context.setFormTwoFieldThree(e.target.value)}
/>
</form>
);
};
export default FormTwo;
可以對上述兩個組件進行一些改進,但它們旨在作為如何將子組件連接到提升狀態(tài)的示例。也可以使用 連接到單個父組件props,但這是效率最低的選項,并且會使您的體系結構混亂。
關鍵要點:將 Redux 用于您的用例。如果正確實施,這是最有效的選擇。
TA貢獻1798條經(jīng)驗 獲得超7個贊
提升狀態(tài)確實是這樣做的正確方法。要優(yōu)化子部分,您可以使用
PureComponent ==> https://reactjs.org/docs/react-api.html#reactpurecomponent
AKA 記憶組件 ==> https://reactjs.org/docs/react-api.html#reactmemo
React.memo 是一個高階組件。它類似于 React.PureComponent 但用于函數(shù)組件而不是類。
此外,如果您在鉤子宇宙結帳中
useCallback :https ://reactjs.org/docs/hooks-reference.html#usecallback
使用備忘錄: https ://reactjs.org/docs/hooks-reference.html#usememo
如果您有任何機會使用 Redux,請記得查看
TA貢獻1805條經(jīng)驗 獲得超9個贊
將所有表單包裝在一個僅處理保存所有表單數(shù)據(jù)并運行“全部保存”功能的組件中:
包裝器組件應該有一個包含所有表單數(shù)據(jù)的狀態(tài),它應該看起來像這樣:
class Wrapper Component extends React.Component {
constructor(props) {
super(props);
this.state = {
formsData: {},
};
}
}
formsData 的結構應該差不多是這樣的: { 0: { title:"text", type:"video", etc:"etc" }, 1: { title:"text", type:"video", etc: "etc" }} 鍵(0,1 等)代表表單 ID,并且可以設置為每個 for 具有的任何唯一修飾符。
然后讓包裝器組件處理每個單獨表單的 onChange -> 每個單獨表單上的每次更改都應該提升新狀態(tài)(新更新的數(shù)據(jù))并相應地更新 formsData 狀態(tài) obj:
const onChange(formData) {
const formattedData = {[formData.id]: {...formData}}
this.setState({formsData: {...formsData, ...formattedData}})
}
* 這只是一個例子,在每個表單的每次更改中,您都會提升整個數(shù)據(jù)對象,您可以通過多種方式進行操作
比,保存所有按鈕也應該在包裝器組件中處理,并將您使用它存儲的所有數(shù)據(jù)提升到父組件中的相關功能/自行處理。
添加回答
舉報
