我使用的是反应支持挂钩的alpha版本,并且想要验证我在间隔后没有更新的情况下更新组件文本的方法,而不需要更改道具时所需的次数
编辑:为清楚起见,该组件正在
moment(timepoint).fromNow()
函数(docs here)中调用formatTimeString
,因此更新并非完全不必要诺言!
我以前有:
const FromNowString = ({ timePoint, ...rest }) => {
const [text, setText] = useState(formatTimeString(timePoint));
useEffect(() => {
setText(formatTimeString(timePoint));
let updateInterval = setInterval(
() => setText(formatTimeString(timePoint)),
30000
);
return () => {
clearInterval(updateInterval);
};
}, [timePoint]);
// Note the console log here is so we can see when renders occur
return (
<StyledText tagName="span" {...rest}>
{console.log('render') || text}
</StyledText>
);
};
“有效”-如果道具发生更改,组件会正确更新,并且组件会在每个间隔更新,但是,并且在道具发生更改时,组件会渲染两次。
>这是因为useEffect
在timePoint
的值更改时在之后运行渲染,并且在我的useEffect
回调中,我立即调用了setState
方法可触发其他渲染。
很明显,如果我删除对setText
的调用,则当prop更改时(直到间隔运行),该组件似乎没有更改,因为text
仍然相同。
我终于意识到我可以通过设置一个我实际上不需要的状态变量来触发渲染,就像这样:
const FromNowString = ({ timePoint, ...rest }) => {
// We never actually use this state value
const [, triggerRender] = useState(null);
useEffect(() => {
let updateInterval = setInterval(() => triggerRender(), 30000);
return () => {
clearInterval(updateInterval);
};
}, [timePoint]);
return (
<StyledText tagName="span" {...rest}>
{console.log("render") || formatTimeString(timePoint)}
</StyledText>
);
};
这非常好用,该组件在安装时仅渲染一次,并且在timePoint
道具更改时仅渲染一次,但是感觉很hack。这是处理事情的正确方法,还是我缺少什么?
答案 0 :(得分:1)
我认为这种方法看起来不错。我要进行的主要更改是每次实际更改值,以使其改为:
const FromNowString = ({ timePoint, ...rest }) => {
const [, triggerRender] = useState(0);
useEffect(() => {
const updateInterval = setInterval(() => triggerRender(prevTriggerIndex => prevTriggerIndex + 1), 30000);
return () => {
clearInterval(updateInterval);
};
}, [timePoint]);
return (
<StyledText tagName="span" {...rest}>
{console.log("render") || formatTimeString(timePoint)}
</StyledText>
);
};
我有两个建议这样做的理由:
setState
可靠地触发了一次重新渲染(React不太可能更改此设置,因为它会破坏太多),但是查看此代码的人会怀疑“ React是否保证重新渲染? setState
通话不会导致状态发生任何变化吗?”即使保持不变,setState
总是会触发重新渲染的主要原因是因为对现有状态进行了突变后可能会调用setState
,但是如果现有状态为null并且未传递任何内容,对于设置人员,在这种情况下,React 可以知道自上次渲染以来状态没有改变并对其进行优化。我不会强迫某人研究React的确切行为,也不担心这种行为将来是否会改变,我会对状态进行实际更改。