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