在 React.js 中通过单击按钮更改函数状态不会触发重新渲染
Changing state in a function from a button click does not trigger a rerender in React.js
我在 React 中有一个单元格矩阵 - 小矩形 - 和一个按钮。单击按钮,我想清除所有单元格。首先,我创建了许多带有一些非空单元格的空单元格,并将其传递给 CellGrid 组件,该组件可以很好地渲染所有单元格。我将按钮 onClick 链接到一个函数,该函数会更改状态 (this.state.cells),但它不会触发子组件 (CellGrid) 中的重新呈现。
class Playfield extends React.Component {
constructor(props){
super(props);
this.clearButtonClick = this.clearButtonClick.bind(this);
}
componentWillMount(){
var arr = [];
for (var i=0; i < 64*64; ++i){ // all empty cells at first
arr.push({id:i, status: "empty"});
}
for (var i=0; i < startCells.length; ++i){ // mark special cells
var newIndex = startCells[i].x + 64*startCells[i].y;
arr[newIndex].status = "alive";
}
this.setState({ // change state
cells: arr
});
}
clearButtonClick(){
console.log("clear")
var newArr = [];
for (var i=0; i < this.state.cells.length; ++i){ // all empty cells again
newArr.push({id:i, status: "empty"});
}
this.setState({ // change state --- NOT UPDATING THE RENDER
cells: newArr
});
}
render(){
return (
<div className="Playfield">
<CellGrid grid_cells={this.state.cells}/>
<Button onClick={this.clearButtonClick}>CLEAR</Button>
</div>
);
}
}
CellGrid 看起来像这样。
class CellGrid extends React.Component {
constructor(props){
super(props);
this.renderCells = this.renderCells.bind(this);
}
renderCells(){
return (this.props.grid_cells.map(function(cell){
return (
<Cell id={cell.id} status={cell.status}/>);
}));
}
render(){
return (
<div className="CellGrid">
{this.renderCells()}
</div>
);
}
}
有人得到提示吗?相关问题都把状态改错了。
它确实有效;你可以在 CellGrid 的 render 方法中放置一个控制台日志,以查看当你单击清除时触发渲染。问题实际上出在您的 <Cell>
组件中。
<Cell>
似乎只在初始安装时使用 props 的状态,它将 status
从 props 复制到它自己的内部状态,然后单元格的渲染来自 this.state.status
而不是this.props.status
。我想你这样做是为了使用 onClick 来切换单元格。您可能想要做的是摆脱 <Cell>
中的本地状态并始终使用 this.props.status
渲染它,并且还只是将 onClick 从 <Playfield>
传递到 <CellGrid>
然后从 <CellGrid>
到每个 <Cell>
.
此外,确保在渲染数组中的组件时使用 key=
属性(如 <CellGrid>
)。
我在 React 中有一个单元格矩阵 - 小矩形 - 和一个按钮。单击按钮,我想清除所有单元格。首先,我创建了许多带有一些非空单元格的空单元格,并将其传递给 CellGrid 组件,该组件可以很好地渲染所有单元格。我将按钮 onClick 链接到一个函数,该函数会更改状态 (this.state.cells),但它不会触发子组件 (CellGrid) 中的重新呈现。
class Playfield extends React.Component {
constructor(props){
super(props);
this.clearButtonClick = this.clearButtonClick.bind(this);
}
componentWillMount(){
var arr = [];
for (var i=0; i < 64*64; ++i){ // all empty cells at first
arr.push({id:i, status: "empty"});
}
for (var i=0; i < startCells.length; ++i){ // mark special cells
var newIndex = startCells[i].x + 64*startCells[i].y;
arr[newIndex].status = "alive";
}
this.setState({ // change state
cells: arr
});
}
clearButtonClick(){
console.log("clear")
var newArr = [];
for (var i=0; i < this.state.cells.length; ++i){ // all empty cells again
newArr.push({id:i, status: "empty"});
}
this.setState({ // change state --- NOT UPDATING THE RENDER
cells: newArr
});
}
render(){
return (
<div className="Playfield">
<CellGrid grid_cells={this.state.cells}/>
<Button onClick={this.clearButtonClick}>CLEAR</Button>
</div>
);
}
}
CellGrid 看起来像这样。
class CellGrid extends React.Component {
constructor(props){
super(props);
this.renderCells = this.renderCells.bind(this);
}
renderCells(){
return (this.props.grid_cells.map(function(cell){
return (
<Cell id={cell.id} status={cell.status}/>);
}));
}
render(){
return (
<div className="CellGrid">
{this.renderCells()}
</div>
);
}
}
有人得到提示吗?相关问题都把状态改错了。
它确实有效;你可以在 CellGrid 的 render 方法中放置一个控制台日志,以查看当你单击清除时触发渲染。问题实际上出在您的 <Cell>
组件中。
<Cell>
似乎只在初始安装时使用 props 的状态,它将 status
从 props 复制到它自己的内部状态,然后单元格的渲染来自 this.state.status
而不是this.props.status
。我想你这样做是为了使用 onClick 来切换单元格。您可能想要做的是摆脱 <Cell>
中的本地状态并始终使用 this.props.status
渲染它,并且还只是将 onClick 从 <Playfield>
传递到 <CellGrid>
然后从 <CellGrid>
到每个 <Cell>
.
此外,确保在渲染数组中的组件时使用 key=
属性(如 <CellGrid>
)。