简体   繁体   中英

React: Cant call setState on a component that is not yet mounted

I'm creating a simple todo app using react(MERN stack). The above warning appears when I try to call a get API with axios and setState at the same time. I've gone through other threads on stack overflow with the same problem but none of them were really that useful. I've even tried messing around with a "isMounted" variable. Below is my code...

export default class App extends React.Component{
  _isMounted = false;

  constructor(props){
    super(props);
    this.state = {list:[], itemCounter: 0};
    this.addItem = this.addItem.bind(this);
    this.handleDone = this.handleDone.bind(this);
    this.componentDidMount = this.componentDidMount(this);
  }
  
  componentDidMount(){
    this._isMounted = true;

    axios.get(`http://localhost:8000/todo/api/`)
      .then(res => {
        if(this._isMounted){
          const list = res.data;
          const unDoneList = list.filter(task => task.done === false)
          this.setState({ list: list, itemCounter: unDoneList.length });
      }});
  }

  componentWillUnmount() {
    this._isMounted = false;
  }

  addItem(val) {
    axios.post('http://localhost:8000/todo/api/task/', { data: val })
    .then(res => {
      const itemCounter = this.state.counter + 1;
      const updatedList = this.state.list;
      updatedList.push({ data: val, done: false });
      console.log(res);
      console.log(res.data);
      this.setState({ list: updatedList, itemCounter: itemCounter });
    })
  }
  
  handleDone(item){
    console.log(item._id)
    axios.post(`http://localhost:8000/todo/api/delete/${item._id}`)
    .then(() => console.log("Item Deleted."));

    let updatedList = this.state.list;
    updatedList.forEach(task => {
      if(task.id === item.id ){
        task.done = true;
      }
    });    
    const itemCounter = this.state.itemCounter - 1;
    this.setState({ list: updatedList, itemCounter: itemCounter });
  }

  render(){
    return (
      <div className="App">
      <nav className="panel is-primary light">
        <Title itemCount={this.state.itemCounter}></Title>
        <Add addItem={this.addItem}></Add>
        <Items items={this.state.list} handleDone={this.handleDone}></Items>
      </nav>  
      </div>
    );
  }
}

For reference, I've uploaded my entire project on GitHub: https://github.com/mohnishm/Todo-App-in-React How do I get rid of this warning?

You are calling componentDidMount lifecycle method inside your constructor, you should not do that.

Here is the problem:

this.componentDidMount = this.componentDidMount(this);

If you do that inside the constructor you would get that warning, React is telling you that the component is not yet mounted but you have already called setState through the manual call to the componentDidMount .

In your case the constructor has not finished executing and the component didn't get a chance to get mounted on to the DOM. Once the constructor is executed, the component is initialized and then the component is actually mounted on to the DOM.

With the component mounted, your lifecycle method componentDidMount would be invoked by React with the proper context (so there is no need to call bind on componentDidMount ) and then at that point of time you should call setState to alter the state of the component.

Also you can remove the _isMounted and the checks related to that property form componentDidMount and componentWillUnmount as it is not required.

componentDidMount is a lifecycle methods and doesnt require initilization inside the constructor. Remove it to avoid the warning.

  constructor(props){
    super(props);
    this.state = {list:[], itemCounter: 0};
    this.addItem = this.addItem.bind(this);
    this.handleDone = this.handleDone.bind(this);
    this.componentDidMount = this.componentDidMount(this); // remove this, componentDidMount is a lifecycle method.
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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