如何使用setInterval()更改某个组件的状态?
问题描述:
我该如何让每2秒我的状态随机更改?现在它在控制台日志中发生变化,但不会呈现它。 活动状态更改应该可视化地更改组件开关组件。例如,如果我排除boxList[0].machines[0].switches[0].active = true
它会正确更改,但当它位于setInterval()中时,它不会更改任何内容。如何使用setInterval()更改某个组件的状态?
实施例:
App.js
var boxList= [
{id: 1, machines:[
{id: 1, switches:[{id: 1, active: false}, {id: 2, active: false}, {id: 3, active: false}, {id: 4, active: false}]},
{id: 2, switches:[{id: 1, active: false}, {id: 2, active: false}, {id: 3, active: false}, {id: 4, active: false}]},
{id: 3, switches:[{id: 1, active: false}, {id: 2, active: false}, {id: 3, active: false}, {id: 4, active: false}]},
{id: 4, switches:[{id: 1, active: false}, {id: 2, active: false}, {id: 3, active: false}, {id: 4, active: false}]},
]},
{id: 2, machines:[
{id: 1, switches:[{id: 1, active: false}, {id: 2, active: false}, {id: 3, active: false}, {id: 4, active: false}]},
{id: 2, switches:[{id: 1, active: false}, {id: 2, active: false}, {id: 3, active: false}, {id: 4, active: false}]},
{id: 3, switches:[{id: 1, active: false}, {id: 2, active: false}, {id: 3, active: false}, {id: 4, active: false}]},
{id: 4, switches:[{id: 1, active: false}, {id: 2, active: false}, {id: 3, active: false}, {id: 4, active: false}]},
]},
]}];
class App extends React.Component {
render() {
setInterval(() => {
var x = [0,1].sample()
var x = [0,1].sample()
var z = [0,1,2,3].sample()
var info = [true, false].sample()
boxList[x].machines[y].switches[z].active = info;
}, 2000);
var boxes = boxList.map((box) =>
<Box key={box.id} box_id={box.id} machines={box.machines} />);
return (
<div>
{boxes}
</div>
);
}
}
答
你的组件不具有状态,它访问一些全局可用的数据。然而,实际的问题是,你永远不会告诉组件重新渲染。该组件不知道数据已更改,因此不会更新。
如果您不想将数据移动到组件的状态,则可以使用forceUpdate
强制重新渲染。
但:render
方法不应该直接或间接地进行另一个渲染。在render
中调用setInterval
也没什么意义,因为每次组件呈现时都会创建一个新的时间间隔。
取而代之,使用lifecycle methods并在组件安装后创建间隔。不要忘记清除组件被破坏的时间间隔!
class App extends React.Component {
componentDidMount() {
this._interval = setInterval(() => {
// ...
this.forceUpdate();
}, 2000);
}
componentWillUnmount() {
clearInterval(this._interval);
}
render() {
// ...
}
}