Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op

Tags:

reactjs

componentDidMount(prevProps, prevState, prevContext) {     let [audioNode, songLen] = [this.refs.audio, List.length-1];      audioNode.addEventListener('ended', () => {         this._endedPlay(songLen, () => {             this._currSong(this.state.songIndex);             this._Play(audioNode);         });     });      audioNode.addEventListener('timeupdate', () => {         let [remainTime, remainTimeMin, remainTimeSec, remainTimeInfo] = [];          if(!isNaN(audioNode.duration)) {             remainTime = audioNode.duration - audioNode.currentTime;             remainTimeMin = parseInt(remainTime/60);  // 剩余分             remainTimeSec = parseInt(remainTime%60);  // 剩余秒              if(remainTimeSec < 10) {                 remainTimeSec = '0'+remainTimeSec;             }             remainTimeInfo = remainTimeMin + ':' + remainTimeSec;             this.setState({'time': remainTimeInfo});         }     }); }  componentWillUnmount () {     let audio = this.refs.audio;     audio.removeEventListener('timeupdate');     audio.removeEventListener('ended'); } 

Error:

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 undefined component.

I removeEventListener 'ended' in componentWillUnmount, but it is not working. because I add this.setState({'time': remainTimeInfo}); in componentDidMount.

like image 378
useLess liang Avatar asked Dec 31 '15 09:12

useLess liang


People also ask

Can only update a mounted or mounting component?

Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op. Warning: Can't call setState (or forceUpdate) on an unmounted component.

Can't call setState or forceUpdate on an unmounted component This is a no-op?

Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.

Can set state on unmounted component?

Summary. Seeing called setState() on an unmounted component in your browser console means the callback for an async operation is still running after a component's removed from the DOM. This points to a memory leak caused by doing redundant work which the user will never benefit from.

How do I mount a setState in component?

You may call setState() immediately in componentDidMount(). It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won't see the intermediate state.


1 Answers

I solved this by assigning a ref to the component and then checking if the ref exists before setting the state:

myMethod(){   if (this.refs.myRef)     this.setState({myVar: true}); }  render() {   return (     <div ref="myRef">       {this.state.myVar}     </div>   ); } 

And lately, since I am using mostly functional components, I am using this pattern:

const Component = () => {   const ref = React.useRef(null);   const [count, setCount] = React.useState(0);    const increment = () => {     setTimeout(() => { // usually fetching API data here       if (ref.current !== null) {         setCount((count) => count + 1);       }     }, 100);   };    return (     <button onClick={increment} ref={ref}>       Async Increment {count}     </button>   ); }; 
like image 152
Tudor Morar Avatar answered Sep 23 '22 04:09

Tudor Morar