You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Hookstate状态赋值数组触发HOOKSTATE-201错误如何解决?

问题原因

@hookstate/core的useState返回的状态对象调用.get()方法时,默认返回的是只读的状态代理,并非可修改的原生JS数组。你直接对这个代理对象的子元素赋值,相当于直接修改Hookstate托管的状态源,触发了框架的直接修改拦截规则,因此抛出HOOKSTATE-201错误。
你用原生React useState时能正常运行,只是因为React本身不会拦截引用类型的直接修改操作(这种写法本身不符合React最佳实践,只是不会显式报错)。

解决方案

方案1:使用Hookstate原生修改语法(更推荐)

Hookstate本身支持直接对嵌套状态调用set方法修改,不需要手动拷贝状态副本,代码更简洁,符合框架设计规范。修改后的flipCellsAround逻辑如下:

const flipCellsAround = (coord) => {
  let [y, x] = coord.split("-").map(Number);

  function flipCell(y, x) {
    if (x >= 0 && x < props.ncols && y >= 0 && y < props.nrows) {
      // 直接对嵌套状态调用set方法修改
      board[y][x].set(oldVal => !oldVal);
    }
  }

  flipCell(y, x);
  flipCell(y, x - 1);
  flipCell(y, x + 1);
  flipCell(y - 1, x);
  flipCell(y + 1, x);

  // 检查获胜逻辑,获取原生数组判断即可
  if (board.get({ noproxy: true }).every(row => row.every(cell => !cell))) {
    hasWon.set(true);
  }
}

方案2:手动拷贝状态为原生数组再修改

如果要沿用你原来的修改逻辑,只需要在获取状态时拷贝一份原生可修改的数组副本即可,二维数组需要做两层浅拷贝或者直接深拷贝:

// 替换原代码中的let tmpBoard = board.get();
// 方式一:两层浅拷贝
let tmpBoard = board.get({ noproxy: true }).map(row => [...row]);
// 方式二:结构化深拷贝,适合更复杂的嵌套结构
// let tmpBoard = structuredClone(board.get());

拷贝完成后后续的修改、set逻辑都不需要调整,即可正常运行。

内容的提问来源于stack exchange,提问作者Troublegum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:27:04