所以我有一个看起来像这样的组件
const App = () => {
const someContextValue = useSomeContext(); //custom hook that calls useContext
useEffect(() => {
someContextValue()
}, [someContextValue]);
return <div />
}
每当组件重新渲染时,即使某些上下文值并没有真正改变,也会触发 useEffect。
我通过使用 useMemo 来解决这个问题,比如
const someContextValue = useMemo(useSomeContext, [useSomeContext])
现在,someContextValue 不会在重新渲染时发生变化。但我觉得这不太对劲。正确的方法是什么?
如果要从上下文中返回对象{}
或数组[]
,则上下文值已更改。
someContextValue
变量在组件内部定义。
组件是一个函数,当函数运行时,其中定义的值将被定义。例如,如果您的上下文返回一个包含状态值的对象,则该对象与上一个呈现中的实例不同,并且您的useEffect
因此而运行。
useEffect
将按引用类型的实例而不是其中的值来比较引用类型。
当您调用useSomeContext()
时,您正在创建一个新对象,并且每次组件渲染时都会发生这种情况。
这与useState
中的状态值不同,其中状态值不会被重新定义。useState
钩子维护该值的相同实例,因此不会每次都重新创建该值,并且useEffect
看到状态值是同一实例。
这就是为什么在使用上下文时,您应该解构上下文对象并引用对象内部的值,这些值要么是从上下文中的useState
钩传递的状态值,要么是在上下文中定义的值,该值在使用组件重新呈现时不会重新定义(因为在这种情况下上下文不会重新呈现(:
const { someStateValue } = useSomeContext()
useEffect(() => {
someStateValue()
}, [someStateValue]);