【问题标题】:Can the multiple context pattern prevent rerenders?多上下文模式可以防止重新渲染吗?
【发布时间】:2021-08-15 20:24:32
【问题描述】:

我目前正在研究如何管理全局状态。一种似乎很流行的模式是多上下文模式:

export default function makeStore<State, Actions = string>(
    reducer: Reducer<State, Actions>,
    initalState: State
): [
    ({ children }: { children: ReactElement }) => JSX.Element,
    () => Dispatch<Actions>,
    () => State
] {
    const dispatchContext = createContext<Dispatch<Actions>>(() => null);
    const storeContext = createContext<State>(initalState);

    const StoreProvider = ({ children }: { children: ReactElement }) => {
        const [store, dispatch] = useReducer<Reducer<State, Actions>>(
            reducer,
            initalState
        );

        return (
            <dispatchContext.Provider value={dispatch}>
                <storeContext.Provider value={store}>
                    {children}
                </storeContext.Provider>
            </dispatchContext.Provider>
        );
    };

    function useDispatch() {
        return useContext(dispatchContext);
    }

    function useStore() {
        return useContext(storeContext);
    }

    return [StoreProvider, useDispatch, useStore];
}

这里的想法是,将dispatchstate 分离到它们自己的上下文中可以以某种方式避免不必要的重新渲染。通过使用useDispatchuseState,组件可以“订阅”仅状态或调度。在处理了一两分钟后,我发现自己想知道这种模式对重新渲染有何影响。

据我所知,每当状态发生变化时,React 都会重新渲染提供者下方的所有内容。将dispatch 分离到它们自己的上下文中会对 e 产生影响。 G。挂钩的依赖数组(使渲染性能更高)也应该可以忽略不计,因为调度是跨渲染的稳定值。

与仅使用一个上下文相比,使用这种模式有什么优势吗?

【问题讨论】:

    标签: reactjs react-hooks react-context


    【解决方案1】:

    这里的诀窍是不仅将 store 和 dispatch 分离到不同的上下文中,还包括使用它们的组件。

    当您有一个分派一个动作并消耗存储值的组件时,此模式无效。即使dispatch 不会触发重新渲染,但由于组件正在使用存储中的值,它会重新渲染。

    因此,如果您将 dispatches 操作的组件与使用它的组件隔离开来,那么这种模式将是有效的。

    还使用 React.memo 将上下文中使用 dispatch 的组件包装起来,以避免重新渲染。因为useReducer 保证dispatch 的引用在重新渲染之间不会改变。

    https://reactjs.org/docs/hooks-reference.html#usereducer

    https://reactjs.org/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down

    【讨论】:

    • 嗯,这就是 redux 的工作方式,因为您可以“订阅”商店(或仅部分商店)。据我所知,这不是上下文的工作方式。我的理解是,当上下文值更改引用时,整个子树都会重新渲染。这包括仅使用 dispatch 以及仅使用 store 值的组件。
    • 更新了我的答案,你也需要使用React.memo
    猜你喜欢
    • 2019-11-23
    • 2013-09-02
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 2013-11-16
    • 2021-01-07
    • 2016-07-26
    相关资源
    最近更新 更多