Как установить состояние в ComponentDidMount

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

Я использовал его в проекте 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

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

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

Спасибо

Пожалуйста, поделитесь полным кодом вашего компонента

Mikhail Sidorov 09.12.2018 01:02

Скорее всего, ваш Slider размонтирован (закрыт / перемещен) до выполнения вызова setState, что дает ошибку.

Roy Wang 09.12.2018 01:02

Отредактировал мое сообщение, чтобы у вас был полный код, я не понимаю, почему мой компонент был бы отключен, это рендеринг html div с: ReactDOM.render (<Slider />, document.getElementById ('home-slider'))

Pierre Ftn 09.12.2018 01:31
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
3
2 244
1

Ответы 1

Как прокомментировал 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);
    }

    ...
}

Другие вопросы по теме