bounty还有2天到期。此问题的答案有资格获得+50声望奖励。user31782正在寻找这个问题的更详细的答案。
正如React文档中提到的:
如果ref回调被定义为一个内联函数,它将在更新期间被调用两次,第一次使用null,然后再次使用DOM元素。这是因为每次render都会创建一个新的函数示例,所以React需要清除旧的ref并设置新的。
我可以理解el
被设置为null
,因为我们需要在重新渲染后释放旧的dom节点的内存。但有两个问题我还是想不通。
1.为什么React必须首先在这里使用null
调用旧的ref回调?难道它不能用新的dom节点调用新的ref回调函数吗?
- React如何清除旧的ref?这和调用ref回调两次有关吗?
6条答案
按热度按时间ifmq2ha21#
你可以 * 考虑 * ref为callback ref重置作为一种效果。不是这样的,但我认为重新措辞的问题确实有助于理解。
假设你将ref回调传递给一个DOM节点:
从效果的Angular 思考会给你:
1.当组件装入时,它将使用该元素调用ref回调
1.当组件卸载时,它调用ref回调函数
null
,因为这是“清理”1.当组件改变时,它首先调用“cleanup”,然后设置新的“effect”。
同样,这是说它使用了真实的的useEffect,但其背后的思想是相同的。
piah890a2#
当React调用ref回调时,它需要知道它是在设置一个新的ref还是在删除一个旧的ref。
通过使用null参数调用旧的ref回调,React向回调发出信号,表示应该清除对**前一个元素的引用。
uwopmtnx3#
示例代码:-
以下是您问题的答案
1.通过首先使用null调用旧的ref回调,React为您提供了一个执行任何特定于旧DOM元素的清理或拆除逻辑的机会。在上面的示例中,在将新的audio元素分配给audioRef.current之前,调用useEffect内部的cleanup函数,允许我们使用audioRef.current.pause()暂停旧的audio元素
aij0ehis4#
如果你想改变ref并且在重新渲染时不变为null,有一个更简单的方法使用state而不是Ref。虽然这是不推荐的东西,如果你正在使用参考,但它会解决问题。
xuo3flqw5#
当React更新组件的渲染输出时,它可能会用新的DOM元素替换旧的DOM元素。为了处理这种变化,React在调用ref回调时遵循两步过程。
首先,React使用null调用旧的ref回调。这允许我们执行与前一个DOM元素相关的任何必要的清理操作。例如,我们可以删除事件侦听器,取消计时器或清理为旧元素设置的任何其他资源。null值表示旧元素正在被卸载,它给了我们一个释放与它关联的任何资源的机会。
在清理步骤之后,React再次调用ref回调,但这次使用新的DOM元素作为参数。在这里,您可以执行更新的元素所需的任何其他设置或操作。我们可以存储对新元素的引用或执行任何其他必要的任务。
简而言之,React首先使用null调用旧的ref回调,以允许与前一个DOM元素相关的清理操作。然后,它用新的DOM元素调用新的ref回调函数,以设置对更新后的元素的引用。这个两步流程确保我们有机会释放资源,并妥善处理新旧元素之间的过渡。
tv6aics16#
React使用
null
调用旧的ref回调,让你有机会清理与旧DOM元素相关的任何资源。如果您有事件侦听器或对旧DOM元素的其他引用,则可以在设置新引用之前释放它们。React通过以
null
作为参数调用ref回调来清除旧的ref,确保旧的DOM引用被删除。通过两次调用ref回调,React确保在设置新ref之前清理旧资源。第一个调用将旧的ref设置为null
,第二个调用将新的DOM元素传递给ref回调。此过程允许您正确管理新旧参照之间的转换。