setState更新状态但不重新呈现

时间:2017-12-12 16:08:04

标签: javascript reactjs

我有一个反应函数来处理表单提交

  handleSubmit(e){
    this.setState({size: this.state.value});
    this.setState({maze : <Maze size={this.state.value}></Maze>}, () => this.forceUpdate());
    console.log('set state finished');
    e.preventDefault();
  }

在具有以下

的app类中
  render() {
    return (
      <div className="App">
        <form onSubmit={this.handleSubmit}>
          <label>Size: </label>
          <input type="number" min="3" step="1" onChange={this.handleChange} value={this.state.value}></input>
          <input type="submit" value="Generate Maze"></input>
        </form>
        {this.state.maze}
      </div>
    );
  }

但是代码并没有让迷宫重新回归; 需要注意的两件事

我在setState回调中放了一个警告,它弹出(意思是,我认为,setState完成了,应该有一个rerender)并在没有重新渲染的情况下传递

强制更新回调不起作用

我该如何解决这个问题?

Main类的完整代码

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      size : 20,
      value : 20,
      showMaze : false
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  componentDidMount(){
    this.setState({maze : <Maze size={this.state.size}></Maze>});
  }

  handleChange(e){
    this.setState({value : e.target.value});
  }

  handleSubmit(e){
    this.setState({size: this.state.value});
    this.setState({showMaze: false});
    this.setState({maze : <Maze size={this.state.value}></Maze>}, () => this.forceUpdate());
    this.setState({showMaze: true});
    e.preventDefault();
  }

  render() {
    return (
      <div className="App">
        <form onSubmit={this.handleSubmit}>
          <label>Size: </label>
          <input type="number" min="3" step="1" onChange={this.handleChange} value={this.state.value}></input>
          <input type="submit" value="Generate Maze"></input>
        </form>
        {this.state.showMaze? this.state.maze : null}
      </div>
    );
  }
}

Maze类的完整代码(减去生成算法)

class Maze extends Component{
  constructor(props){
    super(props);
    this.state = {
      size : this.props.size,
      maze : null
    }; //declare the maze null for now
  }

  componentDidMount(){
    this.generateMazev2(this.props.size);
  }

  generateMazev2 (size){
    //snippped
  }

  render(){
    var renderMaze = new Array(); //store the table
    //calculate the percentage size of each Cell
    var size = 80.0 / this.props.size; //the table should ideally take up 80% of the page
    if(this.state.maze !== null){
      this.state.maze.forEach(function (row, index, arr){
        var newRow = new Array();
        row.forEach(function (box, theIndex, arr){
          newRow[theIndex] = <Cell size={size} top={box.top} bottom={box.bottom} right={box.right} left={box.left}></Cell>;
        });
        renderMaze[index] = <tr>{newRow}</tr>;
      });
      return (<table>{renderMaze}</table>);
    }else{
      return (<p>Generating</p>);
    }


  }
}

2 个答案:

答案 0 :(得分:0)

您可以做的一件事是更改render()方法,如下所示。

render() {
return (
  <div className="App">
    <form onSubmit={this.handleSubmit}>
      <label>Size: </label>
      <input type="number" min="3" step="1" onChange={this.handleChange} value={this.state.value}></input>
      <input type="submit" value="Generate Maze"></input>
    </form>
    {this.state.showMaze? <Maze size={this.state.value}></Maze> : null}
  </div>
);
}

之后修改handleSubmit()方法,如下所示

  handleSubmit(e){
    this.setState({size: this.state.value, showMaze: true});
    console.log('set state finished');
    e.preventDefault();
  }

<强>更新

将组件保持为状态属性不是一个好习惯。因此,在我已经显示的渲染方法中替换{this.state.showMaze? this.state.maze : null}行。

此外,您需要在Maze组件中实现componentWillReceiveProps()方法并根据新的props修改其状态。

componentWillReceiveProps(nextProps) {
   this.setState({size: nextProps.size})
 }

答案 1 :(得分:0)

这不是正确的方法,UI组件不应存储在状态值中。国家应该只包含数据。

<强>解决方案:

在状态变量中保持bool并使用该bool进行Maze组件的条件渲染,bool的初始值将为false并更新handleSubmit(e){ e.preventDefault(); this.setState({size: this.state.value, showMazeCom: true}); } render() { return ( <div className="App"> <form onSubmit={this.handleSubmit}> <label>Size: </label> <input type="number" min="3" step="1" onChange={this.handleChange} value={this.state.value}></input> <input type="submit" value="Generate Maze"></input> </form> {this.state.showMazeCom && <Maze size={this.state.value}></Maze>} </div> ); } 函数内的bool。

像这样:

shouldComponentUpdate(nextProps){
    if(nextProps.size != this.props.size)
        return true;
    return false;
}

更新:

为避免不必要的重新发送迷宫组件,请使用 shouldComponentUpdate 生命周期方法,比较新旧道具值,如果它们不相同则只允许重新渲染

像这样:

{{1}}