3 回答

TA貢獻(xiàn)1744條經(jīng)驗(yàn) 獲得超4個(gè)贊
這是我花了一些時(shí)間與自己斗爭(zhēng)的問(wèn)題。有多種方法可以將子狀態(tài)保持在更高級(jí)別;但是,我發(fā)現(xiàn)在您的特定情況下,通常最好使用 Redux。
需要明確的是,我通常不惜一切代價(jià)避免 Redux(支持 React 的上下文),但 Redux 讓您能夠訂閱子組件中的特定狀態(tài)。當(dāng)您只需要更新一個(gè)子組件時(shí),偵聽(tīng)子組件中的一個(gè)狀態(tài)將阻止您的父組件和兄弟組件更新。這在一次處理多個(gè)表單時(shí)效率更高。
例如,以下組件將僅偵聽(tīng)影響其自身狀態(tài)的狀態(tài)更新。這些更新將繞過(guò)表單父組件和兄弟組件:
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īng)自己的狀態(tài)更新;然而,使用上下文而不是 Redux 的類似邏輯將導(dǎo)致上下文提供者包裝的整個(gè)組件樹(shù)更新(包括父組件和兄弟組件):
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;
可以對(duì)上述兩個(gè)組件進(jìn)行一些改進(jìn),但它們旨在作為如何將子組件連接到提升狀態(tài)的示例。也可以使用 連接到單個(gè)父組件props,但這是效率最低的選項(xiàng),并且會(huì)使您的體系結(jié)構(gòu)混亂。
關(guān)鍵要點(diǎn):將 Redux 用于您的用例。如果正確實(shí)施,這是最有效的選擇。

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超7個(gè)贊
提升狀態(tài)確實(shí)是這樣做的正確方法。要優(yōu)化子部分,您可以使用
PureComponent ==> https://reactjs.org/docs/react-api.html#reactpurecomponent
AKA 記憶組件 ==> https://reactjs.org/docs/react-api.html#reactmemo
React.memo 是一個(gè)高階組件。它類似于 React.PureComponent 但用于函數(shù)組件而不是類。
此外,如果您在鉤子宇宙結(jié)帳中
useCallback :https ://reactjs.org/docs/hooks-reference.html#usecallback
使用備忘錄: https ://reactjs.org/docs/hooks-reference.html#usememo
如果您有任何機(jī)會(huì)使用 Redux,請(qǐng)記得查看

TA貢獻(xiàn)1805條經(jīng)驗(yàn) 獲得超9個(gè)贊
將所有表單包裝在一個(gè)僅處理保存所有表單數(shù)據(jù)并運(yùn)行“全部保存”功能的組件中:
包裝器組件應(yīng)該有一個(gè)包含所有表單數(shù)據(jù)的狀態(tài),它應(yīng)該看起來(lái)像這樣:
class Wrapper Component extends React.Component {
constructor(props) {
super(props);
this.state = {
formsData: {},
};
}
}
formsData 的結(jié)構(gòu)應(yīng)該差不多是這樣的: { 0: { title:"text", type:"video", etc:"etc" }, 1: { title:"text", type:"video", etc: "etc" }} 鍵(0,1 等)代表表單 ID,并且可以設(shè)置為每個(gè) for 具有的任何唯一修飾符。
然后讓包裝器組件處理每個(gè)單獨(dú)表單的 onChange -> 每個(gè)單獨(dú)表單上的每次更改都應(yīng)該提升新?tīng)顟B(tài)(新更新的數(shù)據(jù))并相應(yīng)地更新 formsData 狀態(tài) obj:
const onChange(formData) {
const formattedData = {[formData.id]: {...formData}}
this.setState({formsData: {...formsData, ...formattedData}})
}
* 這只是一個(gè)例子,在每個(gè)表單的每次更改中,您都會(huì)提升整個(gè)數(shù)據(jù)對(duì)象,您可以通過(guò)多種方式進(jìn)行操作
比,保存所有按鈕也應(yīng)該在包裝器組件中處理,并將您使用它存儲(chǔ)的所有數(shù)據(jù)提升到父組件中的相關(guān)功能/自行處理。
添加回答
舉報(bào)