ReactJS中的setState

时间:2016-07-27 15:54:36

标签: javascript reactjs react-jsx

我是ReactJS的新手,我似乎无法找出为什么以下setState的结果不如我预期的那样(即每秒将值增加1)

import React from 'react';
import ReactDOM from 'react-dom';

class Layout extends React.Component {

    constructor() {
        super();
        this.state = {
            name: "Behnam",
            i: 0
        }
    }

    render() {

        setInterval(() => {
            this.setState({ name : "Behnam" + this.state.i });
            this.setState({ i: this.state.i + 1 });
        }, 1000);

        return (
            <div className="container">
                {this.state.name}
            </div>
        );
    }
}

ReactDOM.render(<Layout />, document.getElementById('app'));

相反,输出字符串会迅速增加(我想尽可能快地反应,试图保持其虚拟DOM更新)。所以我想知道这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:4)

每次更改状态时,都会重新渲染组件。 因为您在render方法中启动了setInterval,所以会得到另一个间隔,它会更改状态,然后重新呈现,等等。

当组件安装时,将setInterval移动到componentDidMount,只调用一次:

import React from 'react';
import ReactDOM from 'react-dom';

class Layout extends React.Component {

    constructor() {
        super();
        this.state = {
            name: "Behnam",
            i: 0
        }
    }

    componentDidMount() { set the interval after the component mounted, and save the reference
        this.interval = setInterval(() => {
            this.setState({ 
                name: `Behnam${this.state.i}`, 
                i: this.state.i + 1
            });
        }, 1000);
    }

    componentWillUnmount() {
        this.interval && clearInterval(this.interval); // clear the interval when the component unmounts
    } 

    render() {
        return (
            <div className="container">
                {this.state.name}
            </div>
        );
    }
}

ReactDOM.render(<Layout />, document.getElementById('app'));

答案 1 :(得分:1)

目前,它正在创建一个间隔每个时间呈现组件,因此有多个计时器递增该值。您可能希望在componentDidMount()而不是render()中执行此操作。请参阅docs

import React from 'react';
import ReactDOM from 'react-dom';

class Layout extends React.Component {

    constructor() {
        super();
        this.state = {
            name: "Behnam",
            i: 0
        }
    }

    componentDidMount() {
        setInterval(() => {
            this.setState({ name : "Behnam" + this.state.i });
            this.setState({ i: this.state.i + 1 });
        }, 1000);
    }

    render() {
        return (
            <div className="container">
                {this.state.name}
            </div>
        );
    }
}

ReactDOM.render(<Layout />, document.getElementById('app'));

答案 2 :(得分:1)

每次触发渲染时,您都会再次调用setInterval,并在页面上添加活动间隔数。

您应该使用其他生命周期方法,例如componentDidMount。您应该记得保存setInterval返回的时间间隔ID,以便在clearInterval中呼叫componentWillUnmount