ReactJS 中的设置状态

setState in ReactJS

我是 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 更新的速度一样快)。所以我想知道这样做的正确方法是什么?

每次更改状态时,都会重新渲染组件。 因为你在 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'));

目前,它正在创建一个间隔 次呈现组件,因此有多个计时器递增该值。您可能希望在 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'));

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

您也许应该使用另一种生命周期方法,例如 componentDidMount。你要记得保存setInterval返回的区间ID,这样你就可以在componentWillUnmount.

中调用clearInterval