Reputation: 331
I have something strange with a react app,
I used it in a django project and want to re-use it in a laravel project but it doesn't want to work properly ...
Here is the code of my component :
import React from "react"
import {LeftControl, RightControl, CountControl } from './controls'
import {Slide} from './slide'
import axios from "axios"
export default class Slider extends React.Component {
constructor(props){
super(props);
this.state = {
items : [],
active:0
}
}
componentDidMount() {
axios.get('/coming')
.then((res)=>{
this.setState({ items: res.data, active: 0})
});
setInterval( () => {
this.goToNextSlide()
},5000);
}
goToPrevSlide = () => {
const n = this.state.items.length
if (this.state.active == 0) {
this.setState({active : n-1})
} else {
this.setState({active: this.state.active - 1})
}
}
goToNextSlide = () => {
const n = this.state.items.length
if (this.state.active == n-1){
this.setState({active : 0})
} else {
this.setState({active: this.state.active +1})
}
}
render(){
return(
<div className="slider">
<div className="slider__controls">
<CountControl active={this.state.active} length={this.state.items.length} />
<LeftControl goToPrevSlide={this.goToPrevSlide} />
<RightControl goToNextSlide={this.goToNextSlide}/>
</div>
<div className="slider__items">
{
this.state.items
.map((item, i) => (
<Slide active={this.state.active} index={i} key={i} id={item.id} first_name={item.first_name} last_name={item.last_name} role={item.role} conference_date={item.conference_date} thumbnail={item.thumbnail} />
))
}
</div>
</div>
)
}
}
Uncommenting the setState in componentDidMount raise 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.
in Slider
The component works well on my other project ...
Anyone would have an idea what is the problem ?
Thank you
Upvotes: 0
Views: 2403
Reputation: 1545
As riwu commented, you get the warning because the axios call and timer you define in componentDidMount
try to set the state of Slider
after it has been unmounted. Do the following instead:
export default class Slider extends React.Component {
...
constructor(props) {
super(props);
this._isMounted = false;
this.state = {
items : [],
active:0,
}
}
componentDidMount() {
this._isMounted = true;
axios.get('/coming')
.then((res) => {
if (this._isMounted) {
this.setState({ items: res.data, active: 0})
}
});
this.timer = setInterval(() => {
this.goToNextSlide();
}, 5000);
}
componentWillUnmount() {
this._isMounted = false;
clearInterval(this.timer);
}
...
}
Upvotes: 2