jtb*_*des 10 reactjs react-hooks react-strictmode
我用来useRef保存 prop 的最新值,以便稍后可以在异步调用的回调(例如 onClick 处理程序)中访问它。我使用 ref 而不是放入valueuseCallback 依赖项列表,因为我预计该值会频繁更改(当使用新的组件重新渲染时value),但 onClick 处理程序很少被调用,因此它是不值得在每次值更改时为元素分配新的事件侦听器。
function MyComponent({ value }) {\n const valueRef = useRef(value);\n valueRef.current = value; // is this ok?\n\n const onClick = useCallback(() => {\n console.log("the latest value is", valueRef.current);\n }, []);\n\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\nReact Strict Mode的文档让我相信执行副作用通常render()是不安全的。
\n\n由于上述方法[包括类组件
\nrender()和函数组件体]可能会被多次调用,因此\xe2\x80\x99重要的是它们不包含副作用。忽略此规则可能会导致各种问题,包括内存泄漏和无效的应用程序状态。
事实上,当我使用引用访问旧值时,我在严格模式下遇到了问题。
\n我的问题是:是否担心从渲染函数分配的“副作用” ?valueRef.current = value例如,是否存在回调会收到过时值(或来自尚未提交的“未来”渲染的值)的情况?
我能想到的一种替代方案是useEffect确保在组件渲染后更新引用,但从表面上看,这看起来没有必要。
function MyComponent({ value }) {\n const valueRef = useRef(value);\n useEffect(() => {\n valueRef.current = value; // is this any safer/different?\n }, [value]);\n\n const onClick = useCallback(() => {\n console.log("the latest value is", valueRef.current);\n }, []);\n\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n
\n\n例如,是否存在回调会收到过时值(或来自尚未提交的“未来”渲染的值)的情况?
\n
括号是主要关注点。
\n当前之间存在一一对应关系render。(即承诺)
但很长一段时间以来,React 团队一直在谈论可能开始更新的“并发模式” (render被调用),但随后会被更高优先级的更新中断。
在这种情况下,如果引用在被取消的渲染中进行了更新,则引用最终可能与渲染组件的实际状态不同步。
\n很长一段时间以来,这一直是假设,但刚刚宣布,一些并发模式更改将以一种选择加入的方式出现在 React 18 中,startTransition。(也许还有其他一些)
实际上,这在多大程度上是一个实际问题?很难说。 startTransition是选择加入的,所以如果您不使用它,您可能是安全的。无论如何,许多参考更新将相当“安全”。
但如果可以的话,最好还是谨慎行事。
\n更新:现在,react.dev 文档还说不应该这样做:
\n\n\n不要写或读
\nref.current除初始化外,这使得您的组件\xe2\x80\x99s 的行为变得不可预测。
上面的初始化意味着这样的模式:
\nfunction Video() {\n const playerRef = useRef(null);\n if (playerRef.current === null) {\n playerRef.current = new VideoPlayer();\n }\n ....\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
2371 次 |
| 最近记录: |