javascript - 在 SocketIO 事件侦听器中调用 setState 后,React 组件未更新
问题描述
我有一个类组件。我在构造函数中添加了这一行:
this.handleChangedCells = this.handleChangedCells.bind(this);
我在 componentDidMount 中注册了一个 SocketIO 侦听器并像这样调用一个函数
socket.on("changedCells", this.handleChangedCells);
当我收到数据时,我会在控制台中接收数据。问题是该函数调用 this.setState 并且它没有更新组件。我有
handleChangedCells(data) {
console.log(data);
let new_board = this.state.board;
data.map(arr => {
arr.map(obj => {
new_board[obj.ind[0]][obj.ind[1]] = {
color: obj.color,
alive: obj.alive
};
});
});
this.setState({ board: new_board });
}
我拥有的组件如下:
render() {
return (
<div className="boardContainer" style={container_style}>
{this.state.board.map((row, r_ind) => {
return (
<div className="row" key={r_ind}>
{row.map((col, c_ind) => {
return (
<Cell
key={[r_ind, c_ind]}
cell_row_index={c_ind}
cell_col_index={r_ind}
socketProps={socket}
colorProps={this.state.color}
clickedColorProps={col.color}
aliveProps={col.alive}
/>
);
})}
</div>
);
})}
</div>
);
}
如您所见,组件取决于我更新的状态,但是组件未更新......知道这里发生了什么吗?
编辑:这是我的项目的链接https://github.com/Dobermensch/ExpressTest.git有问题的文件是 /client/components/Game.js
编辑 2:board 是包含对象 {color: [x,y,z], alive: boolean} 的数组数组,我正在获取更改的单元格(死单元格)并将它们标记为板上的死单元,所以理想情况下我会去死细胞的索引,并通过 board[row][col] = {color: [x,y,z], alive: false} 将其标记为死
编辑 3:板的数据结构是 [[{}.{},{}],[{},{},{}]] 我正在更改数组中对象的属性
解决方案
当我使用嵌套objects
和array
. 我认为setState
不能很好地处理嵌套更新。
另一个问题出在您的代码中。你实际上是在改变state
.
let new_board = this.state.board;
这里的董事会是一个array
。Javascript 不会深度克隆array
和object
. 您正在将 的 分配给refererence
新board
array
变量。
所以,你能做的只是deep clone
董事会array
。
let new_board = this.state.board.map(item => {...item}); // You may need to handle the multiple levels.
也应该工作JSON.stringy
。JSON.parse
let new_board = JSON.parse(JSON.stringify(array));
一次,您deep clone
拥有state
. 您可以修改数据并setState
触发重新渲染。
更新 1:
当您使用 Cell 的状态来更新它时。重新渲染时不会更新道具值。
因此,您应该在组件中使用getDerivedStateFromProps以Cell
使prop
数据可用于state
.
static getDerivedStateFromProps(props, state) {
return {
r: props.clickedColorProps[0],
g: props.clickedColorProps[1],
b: props.clickedColorProps[2],
alive: props.aliveProps
};
}
请注意,getDerivedStateFromProps
即使状态发生变化,也会在组件的每次重新渲染时执行。因此,您应该在方法内部有一个条件来返回正确的数据。
推荐阅读
- javascript - typeof 函数声明与函数表达式
- python - 将数据框列从对象转换为日期而不是日期时间
- javascript - 在这段代码中,我无法理解“this”关键字
- fortran - 如何正确读写这个文件?
- javascript - 无法从 nodejs 向浏览器发送确切的错误消息
- python - map_blocks with change of dimensions returns IndexError: tuple index out of range
- javascript - 使用javascript将html表导出到excel时出现unicode数据问题
- r - 有没有办法仅在满足条件时才在 R 中创建矩阵?
- javascript - 未捕获的类型错误:无法读取函数未定义的属性“0”
- c - __attribute__((pure)) applied to void function