Reputation: 123
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?
Upvotes: 1
Views: 491
Reputation: 16908
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.
Upvotes: 1
Reputation: 303
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.
}
Upvotes: 1