【发布时间】:2021-04-30 02:02:59
【问题描述】:
我正在编写一些代码,而这段代码非常庞大。我们有这么多子组件(近 300 个),每个子组件都通过 React Context 使用和操作父组件状态中的值。
注意:我没有从头开始编写此代码。这也意味着我要展示的设计不是我想出来的。
问题:因为每个组件都使用相同的状态,所以会发生很多不必要的重新渲染。每个小的状态变化都会导致每个组件重新渲染。它使网络应用程序滞后。从字面上看,当您在字段中输入某些内容时会有延迟。
我认为,当状态发生变化时,函数会被重建,这就是为什么每个孩子都会被更新,因为上下文提供的值会在状态发生变化后发生变化。
此外,我尝试使用useReducer 代替useState,但效果不佳。除此之外,我尝试在每个子组件上使用React.memo,但无论我尝试什么,compare 函数都没有被触发。 compare 函数仅在状态为 props 的父组件上触发。在这一点上,我什至不确定是什么问题:D
为了提供更具体的设计细节,下面是我们如何定义回调并将回调传递给子组件。
定义:
const [formItemState, setFormState] = React.useState<FormItemState>({} as FormItemState);
const getAppState = useCallback(() => ({ state: props.state as AppState }), [props.state]);
const getAppAction = useCallback(() => ({ action: props.action as AppAction }), [props.action]);
const getFormItemError = useCallback((key: string) => formItemErrorState[key], [
formItemErrorState,
]);
const getFormItem = useCallback((key: string) => formItemState[key], [formItemState]);
const updateFormItem = useCallback(
(name: string, formItemData: FormItemData): void => {
const previousState = getFormItem(name);
if (!isEqual(previousState, formItemData)) {
formItemState[name] = formItemData;
setFormState((state) => ({
...state,
...formItemState,
}));
}
},
[formItemState, setFormState]
);
将它们传递给Context.Provider:
return (
<FormContext.Provider
value={{
getAppAction,
getAppState,
getFormItem,
updateFormItem
}}
>
<SomeComponent>
{props.children} // This children contains more than 250 nested components, and each one of them are using these provided functions to interact with the state.
</SomeComponent>
</FormContext.Provider>
);
最后一点:如果需要更多信息,请询问我。谢谢!
【问题讨论】:
标签: reactjs typescript react-hooks react-context