我在我的项目中使用了react hooks。我试图防止在要打开帮助模式的地方重新渲染复杂的按钮/界面。但是,此按钮需要在整个应用程序中使用,而不会引起折旧。有没有一种方法可以使用setter而不强制更新不相关的组件?
这是我可以生成的最简化的代码示例。 这是上下文的提供者:
// Provider.js
export default function ModalProvider(props: React.PropsWithChildren<{}>) {
// adding the event state info
const [helpModalOpen, setHelpModalOpen] = useState(false as any);
const contextValue = {
helpModalOpen,
setHelpModalOpen,
};
return (
<StateContext.Provider value={{...contextValue}}>
{props.children}
</StateContext.Provider>
);
}
export function useModalState() {
const context = useContext(StateContext);
if (!context) {
throw new Error('useModalState must be used within the AppStateProvider');
}
return context;
}
这是无法分解的非常复杂的组件(它是一个视频界面):
// ComplexButtonToOpenHelpModal.js
export default function ComplexComponent() {
const {setHelpModalOpen} = useModalState();
return (
<ExtremelyComplexComponent onClick={setHelpModalOpen} />
);
}
虽然这是一个简单的示例,但我需要在此应用中使用类似的代码。
答案 0 :(得分:0)
一种可能的简单解决方案是将您的上下文分为两部分:
// Provider.js
const ModalOpenContext = React.createContext();
const SetModalOpenContext = React.createContext();
export default function ModalProvider(props: React.PropsWithChildren<{}>) {
// adding the event state info
const [helpModalOpen, setHelpModalOpen] = useState(false as any);
return (
<SetModalOpenContext.Provider value={setHelpModalOpen}>
<ModalOpenContext.Provider value={helpModalOpen}>
{props.children}
</ModalOpenContext.Provider>
</SetModalOpenContext.Provider>
);
}
export function useModalState() {
const context = useContext(ModalOpenContext);
if (!context) {
throw new Error('useModalState must be used within the AppStateProvider');
}
return context;
}
export function useSetModalState() {
const context = useContext(SetModalOpenContext);
if (!context) {
throw new Error('useSetModalState must be used within the AppStateProvider');
}
return context;
}
// ComplexButtonToOpenHelpModal.js
export default function ComplexComponent() {
const setHelpModalOpen = useSetModalState();
return (
<ExtremelyComplexComponent onClick={setHelpModalOpen} />
);
}
您现在正在将稳定的值传递给SetModalOpenContext.Provider
,因此使用useSetModalState
订阅该值的组件将永远不会被强制重新渲染,因为该值不会随着时间变化。
正如您在问题中所指出的,the React docs point out指出:“只要提供商的价值支柱发生变化,作为提供商的后代的所有使用者都将重新呈现。”
因此,实际上,当您知道上下文值的某个部分将发生变化时,防止重新渲染的唯一方法是:1)将上下文拆分为单独的部分(如上所示)或2)使用其他机制在您的应用中传递必要的数据。