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
相关产品推荐
相关产品推荐

