如何模拟 componentDidUpdate
或使用带有数组的 key
支撑来强制我的组件被重置?
我实现了一个组件,它显示一个计时器,当它达到零时执行一个回调。回调的目的是更新对象列表。后者由新的 反应钩 useState
和 useEffect
组成。
state
包含对计时器启动时间和剩余时间的引用。effect
设置每秒调用一次的时间间隔,以更新剩余的时间,并检查是否应该调用回调。
该组件并不意味着重新调度计时器,或者在间隔为零时继续运行,它应该执行回调和空闲。为了让计时器刷新,我希望传递一个数组到 key
,这将导致组件的状态被重置,因此计时器将重新启动。不幸的是,key
必须与字符串一起使用,因此无论数组引用是否更改,都不会产生任何效果。
我还试图通过传递我所关心的数组来推动道具的更改,但是状态得到了维护,因此间隔没有重置。
观察数组中浅层变化以强制仅使用新钩子 API 更新状态的首选方法是什么?
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
function getTimeRemaining(startedAt, delay) {
const now = new Date();
const end = new Date(startedAt.getTime() + delay);
return Math.max(0, end.getTime() - now.getTime());
}
function RefresherTimer(props) {
const [startedAt, setStartedAt] = useState(new Date());
const [timeRemaining, setTimeRemaining] = useState(getTimeRemaining(startedAt, props.delay));
useEffect(() => {
if (timeRemaining <= 0) {
// The component is set to idle, we do not set the interval.
return;
}
// Set the interval to refresh the component every second.
const i = setInterval(() => {
const nowRemaining = getTimeRemaining(startedAt, props.delay);
setTimeRemaining(nowRemaining);
if (nowRemaining <= 0) {
props.callback();
clearInterval(i);
}
}, 1000);
return () => {
clearInterval(i);
};
});
let message = `Refreshing in ${Math.ceil(timeRemaining / 1000)}s.`;
if (timeRemaining <= 0) {
message = 'Refreshing now...';
}
return <div>{message}</div>;
}
RefresherTimer.propTypes = {
callback: PropTypes.func.isRequired,
delay: PropTypes.number
};
RefresherTimer.defaultProps = {
delay: 2000
};
export default RefresherTimer;
试图与 key
一起使用:
<RefresherTimer delay={20000} callback={props.updateListOfObjects} key={listOfObjects} />
试图用道具改变:
<RefresherTimer delay={20000} callback={props.updateListOfObjects} somethingThatChanges={listOfObjects} />
listOfObjects
指的是一个对象数组,其中对象本身不一定会发生变化,因此应该将该数组与 !==
进行比较。通常,该值将来自 Redux
,其中的操作 updateListOfObjects
使数组像这样重新初始化: newListOfObjects = [...listOfObjects]
。