子组件中的setState警告。警告:只能更新已安装或安装的组件

时间:2017-05-17 09:22:17

标签: reactjs ecmascript-6

我有一个页面,它显示项目列表,当用户点击该特定项目时,render()中会调用一个视图组件。

家长:

 constructor(props) {
    super(props);
    this.state = {
      showData : [],
      view : false,
      projectId: ''
    };
    this.buttonHandler = this.buttonHandler.bind(this);
    this.back = this.back.bind(this);
  };


// change view state to true to render diff component
    buttonHandler(){
    this.setState({view:true})
  };



  back(){

    this.setState({view:true})
  }

 render(){

   let compA = (
  <Paper>
        <List>
            <Subheader >New 
            Projects</Subheader>
            {this.state.showData.map(item =>
                <div key={item.title}>
                    <ListItem onClick={()=> 
                   this.buttonHandler()} leftAvatar=
                   {<Avatar icon={<Wallpaper />} />} primaryText=
                   "test" secondaryText="test" />
                    <Divider inset={true} />
                </div>
            )}
        </List>
    </Paper>
);

let compB = (
  <ReviewProject
    back={this.back}/>
);
  return(
      <div>
        {this.state.view?compB:compA}
      </div>
    );
}

儿童补偿B:

constructor(props) {
 super(props);
this.state = {
//some code
};

}
//calls function back from parent which sets state the "view" to false
 dismiss() {
    this.props.back();
  };

当在子节点上调用dismiss()函数以渲染列表组件compA时,会弹出警告:

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the compB component.

有没有办法解决这个问题?什么是从一个组件来回导航到另一个组件的好方法

3 个答案:

答案 0 :(得分:0)

您可以在设置状态之前尝试使用ref,如下所述 函数(){

 if (this.refs.ref) 
   this.setState({view: true});
}

render() {
  return (
    <div ref="ref">{this.state.view}</div>
  );
}

答案 1 :(得分:0)

因为实际上是第一次渲染,所以如果渲染了compA,那么compB就会丢失,因此当react尝试重新渲染时,它找不到缺少的元素。

==&GT;的

render(){                            
    let returnedComp = (
      <Paper>
            <List>
                <Subheader >New Projects</Subheader>
                {this.state.showData.map(item =>
                    <div key={item.title}>
                        <ListItem onClick={()=> 
                       this.buttonHandler()} leftAvatar=
                       {<Avatar icon={<Wallpaper />} />} primaryText=
                       "test" secondaryText="test" />
                        <Divider inset={true} />
                    </div>
                )}
            </List>
        </Paper>
    );

        if (this.state.view) {
            returnedComp = (
              <ReviewProject back={this.back}/>
            );
        }
      return(
          <div>
            {returnedComp}
          </div>
        );
}  

答案 2 :(得分:0)

我找到的解决方案是:

创建名为viewProject组件的第三个组件,以处理AB之间的切换。

class A extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {
    return (
      <div>
        This is component A
        <button onClick={this.props.onGoBClick}>Go to B</button>
      </div>
    )
  }
}

class B extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {
    return (
      <div>
        This is component B
        <button onClick={this.props.onGoAClick}>Go to A</button>
      </div>
    )
  }
}

class ViewContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      view: false,
    }
    this.goToA = this.goToA.bind(this);
    this.goToB = this.goToB.bind(this);
  }

  goToA() {
    this.setState({view: false})
  }

  goToB() {
    this.setState({view: true})
  }

  render() {
    return (
      this.state.view ?
        <B onGoAClick={this.goToA}/>
      :
        <A onGoBClick={this.goToB}/>
    )
  }
}

ReactDOM.render(<ViewContainer />, document.getElementById('app'))