反应如何在传递的函数中使用状态

时间:2019-10-27 10:37:59

标签: reactjs

我正在使用React上下文传递状态。当我的状态更改时,子组件中的状态也会更改(控制台日志显示新值),但是在函数中使用此状态时,它不会在那里更新(console.log显示旧值)。

我需要重新渲染功能吗?怎么样?

  const {user, userInfo, ref} = useSession(); <-- wrapper for useContext
  console.log(userInfo); <--- correct, updated value

  const haalDataOp = async () => {
    console.log(userInfo.enelogic); <--- old value displaying
    ...
  }

我正在通过按钮(onClick)使用功能haalDataOp

正如已经提到的那样,我可以使用useRef,但是我不明白为什么。为什么这个简单的示例起作用(从https://dev.to/anpos231/react-hooks-the-closure-hell-71m中提取),而我的代码却没有:

  const [value, setValue] = useState(1);

  const handleClick = useCallback(
    () => {
      setValue(value + 1)
    },
    [value],
  );

在示例中,我还尝试使用useCallback(在dep数组中带有userInfo),但这不能解决问题。

1 个答案:

答案 0 :(得分:1)

const ... userInfo ...是一个常量,因此在如下组件中:

console.log('render', userInfo.enelogic) // different value in each render
const haalDataOp = async () => {
  console.log('before', userInfo.enelogic) // correct old value
  await update()
  console.log('after', userInfo.enelogic)  // still the same old value
}

return <button onClick={haalDataOp} />

...它将记录:

render old
before old
after old
render new

...因为userInfo中的haalDataOp是一个闭包,引用了原始渲染器中的值。如果您需要访问一个可变的引用,该引用将指向将来渲染中的最新值,则可以useRef

const userInfoRef = useRef()
userInfoRef.current = userInfo

console.log('render', userInfo.enelogic) // different value in each render
const haalDataOp = async () => {
  console.log('before', userInfoRef.current.enelogic) // old value
  await update()
  console.log('after', userInfoRef.current.enelogic)  // should be new value
}

return <button onClick={haalDataOp} />

但是,可能存在竞争条件和/或'after'代码的执行确定性地发生在下一次渲染之前,在这种情况下,您将需要使用其他技巧...

我怀疑正是这种情况需要const {ref} = useSession(),所以请阅读文档。