【发布时间】:2021-06-02 02:41:47
【问题描述】:
我有一个组件,其中存储了一个对象数组,例如:
const [items, setItems] = React.useState([]);
我可以通过点击一个按钮向这个数组中添加一些元素:
const addItem = () => {
setItems(items => [ ...items, { value: 'foo', color: 'yellow' }]);
};
现在,我想让列表中的每个项目每 500 毫秒从黄色闪烁到红色,持续 5 秒。所以我创建了一个通用的计时器函数来帮助我,例如:
const timer = (timeout: number, interval: number, callback: (n: number) => void) => {
const start = new Date().getTime();
let n = 0;
const _timer = setInterval(() => {
if ((new Date().getTime() - start) >= timeout) {
clearInterval(_timer);
} else {
callback(++n);
}
}, interval);
};
我通过在我的组件中执行以下操作来触发该计时器:
React.useEffect(() => {
// I also store the previous state, so that I trigger a timer only when new items
// are added to my array. Yeah not ideal...
if (items.length > previousItems.length) {
const lastItem = items.length - 1;
timer(5000, 500, (n: number) => {
const updatedItems = [ ...items ];
updatedItems[index].color = n % 2 == 0 ? 'yellow' : 'red';
setItems(items => updatedItems);
});
}
});
这种有缺陷的方法可以正常工作,以防我只将项目逐个添加到列表中(例如,计时器在添加新项目之前完成)。但是同时添加多个item的时候就彻底坏了:第一个定时器已经创建并没有考虑到后面添加的所有item。 我知道这种方法根本不理想,但是如果您有更好的方法来实现我想要的,我将不胜感激。谢谢。
【问题讨论】:
标签: reactjs typescript setinterval use-state