【问题标题】:Calling setState from callback updates the state in React Context half the time从回调中调用 setState 会在一半时间内更新 React Context 中的状态
【发布时间】:2021-10-12 15:43:34
【问题描述】:

这里是 CodeSandbox:https://codesandbox.io/s/competent-dream-8lcrt

我已经实现了一个带有 React 上下文的模式,它公开了 1)打开状态 2)模式配置 3)打开和关闭方法

// ...

const onOpenDialog = (mode, config) => {
  setDialogMode(mode)
  if (config) {
    setDialogConfig(config);
  }
}

const onCloseDialog = () => {
  setDialogMode("");
  if (Object.keys(dialogConfig).length > 0) {
    setDialogConfig({})
  }
}

// ...

return (
  <Provider value={{ dialogMode, dialogConfig, onOpenDialog, onCloseDialog }}>
    {children}
  </Provider>
)

在主组件中,我有一个 onClick 处理程序,它调用 onOpenDialog 方法并在其配置对象中传递 onSubmitonClose 回调(这个 onCloseDialog 回调是问题

const { onOpenDialog, onCloseDialog } = useDialog()

// ...

const onClick = () => {
  onOpenDialog("add", {
    data: null,
    onSubmit: (data) => {
      console.log("Form Data: ", data)
    },
    onCancel: onCloseDialog
  })
}

最后,我有一个 FormInModal 组件,它在点击提交和关闭时调用 dialogConfig 对象中传递的两个回调。

const onSubmit = (data) => {
  dialogConfig.onSubmit({
    username: data.username,
    password: data.password
  })
}

const onCancel = () => {
  dialogConfig.onCancel()
}

重现步骤:

  1. 点击Open
  2. 您应该在控制台中看到 1) 对话框打开 2) 传递给 Dialog config 的配置输入有数据,onSubmit 和 onCancel,配置输入已设置为 dialogConfig 状态
  3. 点击取消,您应该会看到 1) 对话框关闭 2) dialogConfig 状态为空 3) dialogConfig 状态未重置

公平地说,3. 工作了一半。这很奇怪,因为 dialogConfig 状态总是在对话框打开时更新。你可以在 React Dev 工具上看到状态更新只有一半时间

【问题讨论】:

  • 密码箱在哪里?我们假设如何繁殖?
  • 你应该为这类问题创建一个沙盒
  • 我准备好了 CSB。刚刚忘记添加链接了……现在更新了
  • 我猜这与关闭导致的陈旧状态有关

标签: javascript reactjs use-state react-context


【解决方案1】:

当尝试从函数闭包访问状态时,这是 React 中的一个已知问题。旧状态在创建闭包时被捕获并由函数返回,即使状态已更新。

解决问题的一种方法是通过以下方式访问更新的状态:

setState(previousState =&gt; newState) 而不是setState(newState)

来自 React 社区的回答:Function that read an outdated sate

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    • 2022-12-09
    • 2017-07-23
    • 2022-08-14
    • 2017-09-16
    • 2020-01-30
    • 1970-01-01
    相关资源
    最近更新 更多