【发布时间】:2020-03-11 11:29:23
【问题描述】:
如果您在上下文 Provider 值中声明一个对象,则任何上下文消费者在提供者重新渲染时总是会重新渲染,因为每次提供者重新渲染时,value 中的对象都会重新声明。
return (
<Provider value={{ /* declared object */ }}>{children}</Provider>
);
良好的提供者value 模式
这是一个很好的模式,因为store 只会在setStore 被调用时改变。
// ParentComponent.js
function ParentComponent() {
const [store, setStore] = useState({ bool: false });
return (
<Context.Provider value={store}>
<button onClick={() => setStore({ ...store, n: { bool: !store.n.bool } })}>
Switch Bool
</button>
<ContextConsumingComponent />
</Context.Provider>
);
}
// ContextConsumingComponent.js
function ContextConsumingComponent() {
const store = useContext(Context);
console.log('Will only run re-render if the `Switch Bool` button is clicked in parent.');
return <p>{JSON.stringify(context.bool)}</p>;
}
// Avoid re-renders if props haven't changed.
export default React.memo(ContextConsumingComponent);
错误的提供者value 模式
这是一个糟糕的模式,因为<Provider value={{}} /> 正在侦听对封闭对象的更改,而不是store 和setStore 引用本身。现实是我们只想真正听听store。
// ParentComponent.js
function ParentComponent() {
const [store, setStore] = useState({ bool: false });
return (
<Context.Provider value={{ store, setStore }}>
<button onClick={() => setStore({ ...store, n: { bool: !store.n.bool } })}>
Switch Bool
</button>
<ContextConsumingComponent />
</Context.Provider>
);
}
问题:
我希望能够在我的上下文消费组件中使用setStore,并且我想了解其他人如何处理这个问题。我相信我可以选择两个提供商选项,但有兴趣看看其他人如何处理这个问题以及如果我错过了任何±。
两个提供者选项:store 和 dispatch
// Two Providers
function ParentComponent() {
const [store, setStore] = useState({ bool: false });
return (
<Store.Provider value={store}>
<Dispatch.Provider value={setStore}>
<button onClick={() => setStore({ ...store, n: { bool: !store.n.bool } })}>
Switch Bool
</button>
<ContextConsumingComponent />
</Dispatch.Provider>
</Store.Provider>
);
}
【问题讨论】:
标签: javascript reactjs react-context