我正在使用React渲染我的网络应用程序所需的一些组件,我有一个带有播放和停止按钮的计时器。我从get请求中检索所有时间记录,并且每次更改时都要重新呈现我的组件,我该怎么做?
我有一切正常工作,但是使用一个简单的setInterval来调用this.forceUpdate()的函数,但这给了我警告:
警告:forceUpdate(...):只能更新已安装或安装的组件。这通常意味着您在未安装的组件上调用了forceUpdate()。这是一个无操作。请检查TimerBox组件的代码。
我的组件:
var TimerBox = React.createClass({
displayName: 'TimerBox',
updateTime: function () {
getTime();
this.forceUpdate();
this.props.records = allRecords(); // get all time records
},
componentDidMount: function () {
setInterval(this.updateTime, 1000); // set interval to each second
},
render: function () {
this.props.records = allRecords();
return (
React.createElement('div', { className: 'main-timer-box' },
React.createElement('div', { className: 'timer-box' }, hours + ' hours, ' + minutes + ' minutes and ' + seconds + ' seconds',
React.createElement(ControlButton, null)),
React.createElement('hr', null)
)
);
}
});
我是reactjs的新手,我开始使用没有jsx,babel或webpack的反应,我现在不想改变整个代码。
我只想知道我可以声明一个属性,然后在每次更改值时使属性调用成为rerender。
谢谢。
答案 0 :(得分:3)
您应该更新组件状态,它将自动重新呈现组件。此外,您必须在componentWillUnmount
生命周期方法中清除超时,以确保仅在未卸载组件时才调用setState
。
updateTime: function () {
getTime();
this.setState({
records: yourRecordsData
})
}
componentDidMount: function () {
this.myTimer = setInterval(this.updateTime, 1000); // set interval to each second
},
componentWillUnmount: function () {
clearInterval(this.myTimer)
},
现在,您可以在渲染函数中使用状态数据,如下所示:this.state.records
。
请注意,React组件在其状态已更新或其父级已重新呈现时会重新呈现。你永远不应该设置组件自己的道具 - 你只能在子组件上设置道具。通常你不应该使用forceUpdate
(说实话,你几乎不需要它)。检查反应docs以获取更多详细信息,并解释为何应避免forceUpdate
。
答案 1 :(得分:2)
这里的问题是你有一个setInterval
,它没有关于何时从DOM卸载组件的概念。因此,一旦组件卸载,setInterval
函数仍然会触发,并尝试更新导致此问题的已卸载组件的状态。
要解决此警告,您只需执行以下操作:
componentDidMount: function () {
this.interval = setInterval(this.updateTime, 1000); // set interval to each second
},
componentWillUnmount: function() {
clearInterval(this.interval);
}
这样做是将this.interval
设置为间隔的计时器ID,然后使用componentWillUnmount
生命周期方法,我们确保清除计时器,使得代码不会在执行之后执行组件已卸载。