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