[英]Best way to get values from multiple complex child components?
提升狀態確實是正確的做法。 要優化子部分,您可以使用
React.memo 是一個高階組件。 它類似於 React.PureComponent 但用於功能組件而不是類。
另外,如果您在 hooks universe checkout 中
如果您有機會使用 Redux,請記得查看
- 重新選擇: https ://github.com/reduxjs/reselect
將所有表單包裝在一個僅處理保存所有表單數據和運行“全部保存”功能的組件中:
包裝組件應該有一個包含所有表單數據的狀態,它應該看起來像這樣:
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,並且可以設置為每個具有的任何唯一修飾符。
然后讓包裝器組件處理每個單獨表單的 onChange -> 每個單獨表單上的每個更改都應該提升新狀態(新更新數據)並相應地更新 formsData 狀態對象:
const onChange(formData) {
const formattedData = {[formData.id]: {...formData}}
this.setState({formsData: {...formsData, ...formattedData}})
}
* 這只是一個例子,在每個表單的每個更改中,你提升了整個數據對象,你可以通過多種方式做到這一點
然后,保存所有按鈕也應該在包裝器組件中處理,並將您存儲的所有數據提升到父組件中的相關功能/自行處理。
祝你好運!
這是我花了一些時間與自己斗爭的問題。 有多種方法可以在更高級別維護子狀態; 但是,我發現在您的特定情況下,通常最好使用 Redux。
明確地說,我通常不惜一切代價避免使用 Redux(支持 React 的上下文),但 Redux 使您能夠訂閱子組件中的特定狀態。 當您只需要一個子組件更新時,監聽子組件中的一個狀態將阻止您的父組件和兄弟組件更新。 當一次處理多個表單時,這最終會更有效率。
例如,下面的組件只會監聽影響自身狀態的狀態更新。 這些更新將繞過表單父組件和同級組件:
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
只監聽它自己的狀態更新; 然而,使用上下文而不是 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;
可以對上述兩個組件進行一些改進,但它們旨在作為如何將子組件連接到提升狀態的示例。 也可以使用props
連接到單個父組件,但這是最低效的選擇,並且會使您的架構混亂。
要點:將 Redux 用於您的用例。 如果正確實施,這是最有效的選擇。
祝你好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.