Reputation: 717
I want to add a typing effect to a component in my React app and I'm using setInterval
to do this. Everything works fine but I'm getting the following error:
Warning: Can't perform a React state update 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
The function starts in componentDidMount()
so I don't understand why it's saying that I'm updating an unmounted component. I've tried to add clearInterval()
in componentWillUnmount()
but the error still shows.
Code:
componentDidMount = () => {
this.typeText();
}
componentWillUnmount(){
console.log(this.state.intervalId);
clearInterval(this.state.intervalId);
}
typeText = () => {
const sp = (text,key) => <span key={key} style={{whiteSpace: 'pre-line'}}>{text}</span>;
const results = this.state.screenText;
let start = 0;
let cursor = 0;
const intervalId = setInterval(() => {
if (results.length) results.pop();
const str = this.state.text.slice(start,cursor);
const span = sp(str,cursor);
results.push(span);
this.setState({screenText:results});
start = Math.floor((cursor / 80));
cursor += 1;
if (cursor > this.state.text.length) clearInterval(intervalId);
},5);
this.setState({intervalId: intervalId});
console.log(this.state.intervalId);
}
render() {
return <span id="typing"> {this.state.screenText}</span>
}
Upvotes: 1
Views: 296
Reputation: 324
I think the problem with your code is that you are saving intervalId
in the state of the component.
As you probably know when you call setState
it causes rerender
.
you can save your intervalId
in the attribute of class.
please consider these changes in your code:
class MyClsss extends React.component{
intervalId = "";
...
}
this.intervalId = setInterval(...)
clearInterval(this.intervalId);
Upvotes: 2