如何在ComponentDidMount中设置状态

时间:2018-12-08 23:52:42

标签: reactjs state mount

我的React应用有些奇怪,

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

}

取消注释componentDidMount中的setState会引发以下错误:

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 :(得分:2)

正如riwu所评论的那样,您会收到警告,因为您在componentDidMount中定义的axios调用和计时器会尝试在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);
    }

    ...
}