如何防止 React with Hooks & Context 中的 child 组件出现不必要的 re-renders?
How can I prevent unnecessary re-renders on the child components in React with Hooks & Context?
我正在编写一些代码,这段代码非常庞大。我们有这么多 child 个组件(将近 300 个),每个组件都通过 React Context 使用和操作来自 parent 组件状态的值。
Note: I didn't wrote this code from scratch. Which also means the design I'm about to show is not what I would come up with.
问题: 因为每个组件都使用相同的状态,所以有很多不必要的 re-renders 发生。每个小的状态变化都会导致每个组件 re-render。它使网络应用程序变得迟钝。从字面上看,当您在字段中输入一些内容时会出现延迟。
我认为,当状态发生变化时,函数会被重建,这就是每个 child 都会更新的原因,因为上下文提供的值在状态发生变化后会发生变化。
此外,我尝试使用 useReducer
而不是 useState
,但效果不佳。除此之外,我尝试在每个 child 组件上使用 React.memo
,但是无论我尝试什么,compare
函数都没有被触发。 compare
函数仅在 parent 组件上触发,该组件具有状态作为道具。在这一点上,我什至不确定问题出在哪里 :D
为了提供有关设计的更多具体细节,以下是我们如何定义回调并将其传递给 child 组件。
定义:
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 只从 props 中提取变化
我正在编写一些代码,这段代码非常庞大。我们有这么多 child 个组件(将近 300 个),每个组件都通过 React Context 使用和操作来自 parent 组件状态的值。
Note: I didn't wrote this code from scratch. Which also means the design I'm about to show is not what I would come up with.
问题: 因为每个组件都使用相同的状态,所以有很多不必要的 re-renders 发生。每个小的状态变化都会导致每个组件 re-render。它使网络应用程序变得迟钝。从字面上看,当您在字段中输入一些内容时会出现延迟。
我认为,当状态发生变化时,函数会被重建,这就是每个 child 都会更新的原因,因为上下文提供的值在状态发生变化后会发生变化。
此外,我尝试使用 useReducer
而不是 useState
,但效果不佳。除此之外,我尝试在每个 child 组件上使用 React.memo
,但是无论我尝试什么,compare
函数都没有被触发。 compare
函数仅在 parent 组件上触发,该组件具有状态作为道具。在这一点上,我什至不确定问题出在哪里 :D
为了提供有关设计的更多具体细节,以下是我们如何定义回调并将其传递给 child 组件。
定义:
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 只从 props 中提取变化