如何防止在 React with Hooks & Context 中的子组件上进行不必要的重新渲染?



我正在编写一些代码,这些代码非常庞大。我们有这么多子组件(近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>
);

最后一条注释:请询问我是否需要更多信息。谢谢

为什么不重写状态管理以redux并只提取每个组件上使用的必要状态呢。React.memo只从道具中获取更改

最新更新