简体   繁体   English

通过单击按钮更改功能中的状态不会触发React.js中的重新渲染

[英]Changing state in a function from a button click does not trigger a rerender in React.js

I've got a matrix of cells - small rectangles - in React and a button. 我在React和一个按钮中有一个单元格矩阵-小矩形。 On a button click, I want to clear all the cells. 在单击按钮时,我要清除所有单元格。 First, I create lots of empty cells with some non-empty ones and pass it down a CellGrid component, which renders all the cells just fine. 首先,我创建了许多带有一些非空单元格的空单元格,并将其传递到CellGrid组件中,这使所有单元格都很好。 I linked the button onClick to a function, which changes the state (this.state.cells), but it does not trigger a rerender in the child component (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>
    );
  }
}

And the CellGrid looks like this. 而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>
    );
  }
}

Anyone got a hint? 有人提示吗? Related questions all changed the state the wrong way. 相关问题都以错误的方式改变了状态。

It's actually working; 它实际上在工作; you can put a console log in the render method of CellGrid to see that render is triggered when you click clear. 您可以将控制台日志放入CellGrid的render方法中,以查看单击清除后触发了渲染。 The problem actually lies within your <Cell> component. 问题实际上出在<Cell>组件内。

<Cell> seems to only use status from props on initial mounting where it copies status from props into it's own internal state and then rendering of the cell comes from this.state.status instead of this.props.status . <Cell>似乎在初始安装只使用从道具状态,其中它复制status从道具到它自己的内部状态,然后使该细胞的来自this.state.status代替this.props.status I imagine you did it this way to use onClick to toggle the cells. 我想您是使用onClick切换单元格的方式。 What you might want to do is get rid of the local state in <Cell> and always render it using this.props.status and just also pass an onClick through from <Playfield> to <CellGrid> and then from <CellGrid> to each <Cell> . 您可能想要做的是摆脱<Cell>中的本地状态,并始终使用this.props.status呈现它,还只需将onClick从<Playfield>传递到<CellGrid> ,然后从<CellGrid>传递给每个<Cell>

Also, make sure you're using the key= property any time you are rendering components from an array (like in <CellGrid> ). 另外,确保从数组渲染组件时都使用key=属性(例如<CellGrid> )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM