Sti*_*nky 3 javascript reactjs react-hooks
我习惯将函数传递给 useState,这样我就不会创建不必要的对象:
useState(() => /* create complex obj */)
Run Code Online (Sandbox Code Playgroud)
我预计 useRef 会以相同的方式工作,但下面返回一个函数,而不是调用它一次来初始化,然后返回先前创建的对象。
useRef(() => /* create complex obj */).current
Run Code Online (Sandbox Code Playgroud)
我想人们可以做这样的事情,但看起来不太干净。
const myRef = useRef();
useEffect(() => {
myRef.current = /* create complex obj */;
}, []);
Run Code Online (Sandbox Code Playgroud)
我错过了什么还是它真的是 useRef 的限制?
更新
澄清一下,这是使用 useState 和 useRef 的常用方法:
useState(createSimpleInitialValue());
useRef(createSimpleInitialValue());
Run Code Online (Sandbox Code Playgroud)
对于每次渲染,您都花时间创建一个初始值,该值将在第一次渲染后被丢弃。这对于简单的对象来说并不重要,但对于复杂的对象有时可能会成为问题。useState 有一个解决方法:
useState(() => createComplexObj());
Run Code Online (Sandbox Code Playgroud)
我们传递的不是对象,而是函数。React 将在第一次渲染时调用该函数,但不会在后续渲染中调用该函数,因此您只需构建该对象一次。我希望 useRef 有这样的功能,但是当你传递一个函数时,它只存储该函数。文档没有提到 useRef 可以接受一个函数,但我希望仍然有一些内置的方法来做到这一点。
正如我在评论中指出的,React Github 存储库上已经对此进行了相当长的讨论。建议了几种解决方法,包括使用useMemo空依赖数组的解决方法 - 但 Dan Abramov(React 核心开发人员之一)在此评论中特别不建议这样做,因为
\n\n\n
useMemo不建议[]用于此用例。将来,我们可能会遇到这样的用例:我们删除useMemo值 \xe2\x80\x94 以释放内存或减少我们保留的内存量,例如隐藏项目的虚拟滚动。您不应该依赖useMemo保留值。
但他接着提供了他自己推荐的解决方法:
\n\n\n我们对此进行了更多讨论,并决定将此模式作为昂贵对象的推荐:
\n
我用一个代码片段代表了下面的要点,同时删除了特定于问题提出者用例并匹配简短代码的细节(如果感兴趣,仍然可以在上面的 Github 链接中看到)您问题中的示例更好:
\nfunction MyComponent() {\n const myRef = useRef(null)\n\n function getComplexObject() {\n let complexObject = myRef.current;\n if (complexObject !== null) {\n return complexObject;\n }\n // Lazy init\n let newObject = /* create complex obj */;\n myRef.current = newObject;\n return newObject;\n }\n\n // Whenever you need it...\n const complexObject = getComplexObject();\n // ...\n}\nRun Code Online (Sandbox Code Playgroud)\n正如您希望看到的,这里的想法很简单,尽管代码有点冗长:我们将 ref 值初始化为,null然后,每当需要时,如果 ref 成立,则计算它并将null其存储在 ref 中,否则使用存储在 ref 中的值。这只是一个非常基本的记忆,但与 React 不同的是useMemo,它完全保证在第一次渲染后不会重新计算值。
| 归档时间: |
|
| 查看次数: |
2471 次 |
| 最近记录: |