在 React 中共享一些全局值和函数的最佳方式是什么?
现在我有一个 ContextProvider ,里面有所有这些:
<AllContext.Provider
value={{
setProfile, // second function that changes profile object using useState to false or updated value
profileReload, // function that triggers fetch profile object from server
deviceTheme, // object
setDeviceTheme, // second function that changes theme object using useState to false or updated value
clickEvent, // click event
usePopup, // second function of useState that trigers some popup
popup, // Just pass this to usePopup component
windowSize, // manyUpdates on resize (like 30 a sec, but maybe can debounce)
windowScroll // manyUpdates on resize (like 30 a sec, but maybe can debounce)
}}
>
但是就像文档中的悲伤一样:因为上下文使用引用标识来确定何时重新渲染,所以当提供者的父级重新渲染时,有一些问题可能会在消费者中触发意外渲染。例如,下面的代码将在每次 Provider 重新渲染时重新渲染所有消费者,因为总是为 value 创建一个新对象:
这不好:
<Provider value={{something: 'something'}}>
还行吧:
this.state = {
value: {something: 'something'},
};
<Provider value={this.state.value}>
我想将来我可能会有多达 30 个上下文提供程序,而且它不是很友好:/
那么如何将这个全局值和函数传递给组件呢?我只能
- 为所有内容创建单独的 contextProvider。
- 将一些一起使用的东西,如配置文件及其功能、主题及其功能(参考标识怎么样?)
- 也许组只是因为不改变自己而起作用?那么参考身份呢?)
- 其他最简单的方法?
我在 Provider 中使用的示例:
// Resize
const [windowSize, windowSizeSet] = useState({
innerWidth: window.innerWidth,
innerHeight: window.innerHeight
})
// profileReload
const profileReload = async () => {
let profileData = await fetch('/profile')
profileData = await profileData.json()
if (profileData.error)
return usePopup({ type: 'error', message: profileData.error })
if (localStorage.getItem('deviceTheme')) {
setDeviceTheme(JSON.parse(localStorage.getItem('deviceTheme')))
} else if (profileData.theme) {
setDeviceTheme(JSON.parse(JSON.stringify(profileData.theme)))
} else {
setDeviceTheme(settings.defaultTheme)
}
setProfile(profileData)
}
// Click event for menu close if clicked outside somewhere and other
const [clickEvent, setClickEvent] = useState(false)
const handleClick = event => {
setClickEvent(event)
}
// Or in some component user can change theme just like that
setDeviceTheme({color: red})