【问题标题】:useContext value changes on rerenders重新渲染时的 useContext 值更改
【发布时间】:2020-05-11 20:09:15
【问题描述】:

所以我有一个看起来像

的组件
const App = () => {
  const someContextValue = useSomeContext();  //custom hook that calls useContext

  useEffect(() => {
    someContextValue()
  }, [someContextValue]);

  return <div />
}

每当组件重新渲染时,即使 someContextValue 并没有真正改变,也会触发 useEffect。

我通过使用 useMemo 来解决这个问题

const someContextValue = useMemo(useSomeContext, [useSomeContext])

现在 someContextValue 在重新渲染时不会改变。但我觉得这不太对。这样做的正确方法是什么?

【问题讨论】:

  • 上下文值已更改。因为值是在组件内部定义的,而组件是一个函数。当一个函数运行时,它内部定义的值被定义。当您调用useSomeContext() 时,您正在创建一个新对象,并且每次组件呈现时都会发生这种情况。这与状态值不同,状态值不会被重新定义,useState 钩子会维护该值的相同实例,因此不会每次都重新创建它。
  • 我已将我的评论添加为更详细的答案。

标签: reactjs react-hooks use-context


【解决方案1】:

如果您从上下文返回对象{} 或数组[],则上下文值已更改。

someContextValue 变量在组件内部定义。

组件是一个函数,当一个函数运行时,它内部定义的值被定义。例如,如果您的上下文返回一个包含状态值的对象,那么该对象与之前的渲染对象是不同的实例,因此您的 useEffect 会运行。

useEffect 将通过实例而不是它们内部的值来比较引用类型。

当您调用useSomeContext() 时,您正在创建一个新对象,并且每次组件呈现时都会发生这种情况。

这与useState 中的状态值不同,其中状态值不会被重新定义。 useState 钩子维护值的相同实例,因此它不会每次都重新创建,useEffect 看到状态值是相同的实例。

这就是为什么在使用上下文时,您应该解构上下文对象并引用对象内部的值,这些值要么是从useState 传递的状态值钩子 inside 上下文,或在使用组件重新渲染时未重新定义的上下文内定义的值(因为在这种情况下上下文不会重新渲染):

const { someStateValue } = useSomeContext()

useEffect(() => {
  someStateValue()
}, [someStateValue]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-12
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    相关资源
    最近更新 更多