我有一个类组件。我在构造函数中添加了这一行:
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:board 的数据结构是 [[{}.{},{}],[{},{},{}]] 我正在更改其中对象的属性数组
最佳答案
我在组合使用嵌套对象
和数组
时遇到过类似的问题。我认为 setState
不能很好地处理嵌套更新。
另一个问题在您的代码中。您实际上是在改变 state
。
let new_board = this.state.board;
这里的棋盘是一个数组
。 Javascript 不会深度克隆array
和object
。您正在将 board
array
的 refererence
分配给新变量。
所以,您可以做的只是深度克隆
板数组
。
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));
曾经,您拥有状态
的深度克隆
。您可以修改数据,setState
应该会触发重新渲染。
更新 1:
因为您正在使用 Cell 的状态来更新它。 Prop 值不会在重新渲染时更新。
所以你应该使用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 - 在 SocketIO 事件监听器中调用 setState 后 React Component 未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58407283/