Как установитьState в ComponentDidMount - PullRequest
0 голосов
/ 09 декабря 2018

У меня есть что-то странное с приложением реагирования,

Я использовал это в проекте django и хочу повторно использовать его в проекте laravel, но он не хочет работать должным образом ...

Вот код моего компонента:

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>
    )
}

}

Раскомментирование setState в componentDidMount вызывает следующую ошибку:

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

Компонент работаетхорошо в моем другом проекте ...

Кто-нибудь мог бы понять, в чем проблема?

Спасибо

1 Ответ

0 голосов
/ 09 декабря 2018

Как прокомментировал riwu, вы получаете предупреждение, потому что вызов axios и таймер, которые вы определили в componentDidMount, пытаются установить состояние Slider после его размонтирования.Вместо этого выполните следующие действия:

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);
    }

    ...
}
...