状态更改后 useEffect 挂钩未触发

2024-01-01

我有两个兄弟组件,它们通过反应中的上下文共享状态。 组件之间共享的状态是一个数组。

如果我更新arr在一个组件中声明,我希望另一个组件侦听该更新并相应地执行某些操作。当我使用useEffect在第二个组件中,我监听以下内容的变化arr状态变量。

例如:

// App Component -------
const App = props => {
 const { arr, setArr } = useContext(GlobalContext)
  
 const handleChange = () => {
   const newArr = arr
   [10, 20, 30, 40].map(v => {
     newArr.push(v)
     setArr(newArr)
   })

  return (...)
}

// App2 (Sibling) Component 
const App2 = props => {
  const { arr, setArr } = useContext(GlobalContext)
  const [localArr, setLocalArr] = useState(0)

  useEffect(
    () => {
      updateLocalState()
    },
    // fire if "arr" gets updated
    [arr]
  )

  const updateLocalState = () => {
    setLocalArr(localArr + 1)
  }

  return (...)
}

The useEffect钩子是only在初始渲染时触发,尽管状态arr更新。

我知道声明一个新变量const newArr = arr我的状态变量是一个引用,所以newArr.push(v)从技术上讲是一种状态突变。但是,状态仍然更新,不会引发警告,并且useEffect什么也没做。

为什么useEffect尽管状态更新了但没有被调用?是因为状态突变吗?

第二个问题:为什么没有抛出有关状态突变的警告或错误?状态突变是危险的 - 如果发生这种情况,我预计会出现某种警告。

现场演示在这里:


作为第二个参数传递给的数组useEffect只检查数组中的元素是否===到之前渲染中的元素。const newArr = arr;将导致newArr === arr因为它不会创建新数组,这不是您想要的。

创建一个新数组,其中包含所有元素arr它会按预期工作。

const App = props => {
 const { arr, setArr } = useContext(GlobalContext)

 const handleChange = () => {
   const newArr = [...arr]
   [10, 20, 30, 40].forEach(v => {
     newArr.push(v)
   })
   setArr(newArr)
 }

  return <>{/* ... */}</>
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

状态更改后 useEffect 挂钩未触发 的相关文章

随机推荐

  • HashMap 中的 Double

    我正在考虑使用 Double 作为 HashMap 的键 但我知道浮点比较是不安全的 这让我开始思考 Double 类上的 equals 方法也不安全吗 如果是 则意味着 hashCode 方法也可能不正确 这意味着使用 Double 作为
  • 当前身份(NT 机构/网络服务)没有写入权限

    我开发了一个简单的网络应用程序 一个标签和一个按钮 单击按钮时 标签将显示 Hello World 当我在 Web 服务器上部署此 Web 应用程序并访问 URL 时 收到此错误消息 当前身份 NT 权威 网络服务 不 有写权限 C Win
  • 在运行时动态设置Python解释器优化

    经过一段时间在这里寻找重复项后 我发现唯一的事情是无操作并使用 Cython 进行优化 这是完全不相关的 我想要完成的是动态设置python O运行时标记 基本上 有一个值sys flags optimize这是只读的 我正在寻找一个选项来
  • 如何在软删除模型上使用资源控制器的 show 方法?

    所以我有一个名为的资源控制器ProjectController我添加了软删除并将其用作存档 Route get project archive ProjectController trash gt name project archive
  • Doxygen-如何记录具有非标准扩展名 (.INI) 的文件

    我有一个简单的问题 如何记录 INI 文件 我有一个具有以下布局的 C 项目 readme txt src main cpp data simple ini 我从 readme txt 和 main cpp 生成文档没有问题 但 simpl
  • 接受不在列表中的值 - bootstrap 组合框

    有没有办法让用户可以在引导组合框中输入其他值 从这个网站 https github com danielfarrell bootstrap combobox https github com danielfarrell bootstrap
  • 如何使用函数从管道中获取对象作为字符串?

    以字符串而不是对象形式输出结果的命令 ls Out String Stream Output Directory C MyPath dir1 Mode LastWriteTime Length Name a 2022 01 22 5 34
  • 我们可以使用 JavaScript 来压缩 PDF 文件吗?如果是,如何进行?如果否,为什么?

    我在浏览器上实现了上传文档功能 用户可以一次上传大约 4 5 个文档 然而 当我们上传文件大小在5MB左右且网络连接较慢 在浏览器的开发工具中设置较慢的3G网络 的文档时 由于网络超时 我们无法上传所有文件 为了成功上传尺寸较大且互联网连接
  • 使用 DQN 增加 Cartpole-v0 损失

    您好 我正在尝试训练 DQN 来解决健身房的 Cartpole 问题 由于某种原因Loss https i stack imgur com uHxpR png看起来像这样 橙色线 你们能看一下我的代码并帮忙解决这个问题吗 我已经对超参数进行
  • 根据条件选择 OpenMP 编译指示

    我有一个想要优化的代码 它应该在各种线程中运行 在我的 for 循环中使用不同的调度技术运行一些测试后 我得出的结论是 最适合的方法是在只有一个线程时执行动态调度 否则进行引导 这在 openMP 中可能吗 更准确地说 我希望能够执行以下操
  • 查找项目并更改自定义对象数组中的值 - Swift

    我有这门课 class InboxInterests var title var eventID 0 var count var added 0 init title String eventID NSInteger count Strin
  • 如何强制 gmail 收件箱重新加载/刷新?

    我构建了一个使用 Gmail API 中的导入端点的应用程序Gmail Users Messages import 克隆电子邮件但允许更改主题 然后 它使用删除端点删除原始 旧消息Gmail Users Messages remove 我想
  • java字节码-小于int的类型的表示

    在我大学的一个项目中 我直接使用 Java 字节码 浏览 JVM 可用指令列表后 http en wikipedia org wiki Java bytecode instruction listings http en wikipedia
  • HTML 图像 src 区分大小写

    我的图像文件夹名称大写 但是src是小写的 所以这不是加载图像 我无法将所有图像文件夹设置为小写 因此我想更改代码以采用不区分大小写的路径 我有一个这样的链接 a href http www google com img src image
  • 构建 Android NDK 项目时出现问题

    我尝试在 Linux Ubuntu 上的 Eclipse 中构建项目 Eclipse 显示错误消息 Build of configuration Default for project FFVideo home art android nd
  • Duck 在 Typescript 中输入 Promise

    假设我有一个日志记录函数 它接受一个函数并记录名称 参数和结果 function log a f args A gt B args A gt B return function args A B console log f name con
  • 使用 jQuery 检查单选按钮后切换内容

    我该如何解决这个问题 我想切换每个单选按钮的内容 如果已选择 另外我如何设置默认选择的单选按钮 option detail hide option click function this next div slideToggle this
  • 如何增加分配给 GlassFish 的内存?

    我想增加 GlassFish 实例的内存分配 有人可以帮我吗 您的答案可以通过管理控制台或命令行 我不介意 找到您正在使用的文件domain xml 即 usr local glassfish 4 1 glassfish domains d
  • 使用枚举绑定组合框选定值

    我无法绑定组合框选定的值 public void InitializePage cbStatus DataSource Enum GetValues typeof CourseStudentStatus 在我的构造函数上 public Ed
  • 状态更改后 useEffect 挂钩未触发

    我有两个兄弟组件 它们通过反应中的上下文共享状态 组件之间共享的状态是一个数组 如果我更新arr在一个组件中声明 我希望另一个组件侦听该更新并相应地执行某些操作 当我使用useEffect在第二个组件中 我监听以下内容的变化arr状态变量