useRef React hook 的确切行为是什么?每次重新渲染时都会重新创建对象吗?

Lik*_*ple 4 reactjs react-hooks

我正在创建一个应用程序,我需要在初始渲染时创建一个对象并在整个组件生命周期中保留它。

\n

我的代码现在看起来像这样:

\n
function Component() {\n  const obj = useRef(new Smth());\n  return (\n    <div>\n      <button onClick={obj.current.p}>p</button>\n      <button onClick={obj.current.c}>c</button>\n    </div>\n  );\n};\n
Run Code Online (Sandbox Code Playgroud)\n

React 文档说:

\n
\n

useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传递的参数 (initialValue)。返回的对象将在组件的整个生命周期内持续存在。

\n
\n

来自: https: //reactjs.org/docs/hooks-reference.html#useref

\n

看来我使用得当。然而,Hooks FAQ 说:

\n
\n

您有时可能还想避免重新创建 useRef() 初始值。例如,也许您想确保某些命令式类实例仅创建一次:

\n
\n
function Image(props) {\n  // \xe2\x9a\xa0\xef\xb8\x8f IntersectionObserver is created on every render\n  const ref = useRef(new IntersectionObserver(onIntersect));\n  // ...\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n
\n

useRef 不接受像 useState 这样的特殊函数重载。相反,您可以编写自己的函数来延迟创建和设置它:

\n
\n
\nfunction Image(props) {\n  const ref = useRef(null);\n\n  // \xe2\x9c\x85 IntersectionObserver is created lazily once\n  function getObserver() {\n    if (ref.current === null) {\n      ref.current = new IntersectionObserver(onIntersect);\n    }\n    return ref.current;\n  }\n\n  // When you need it, call getObserver()\n  // ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n

从:https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables

\n

那么初始值是否会被重新创建呢?

\n

gio*_*gim 5

\n

那么初始值是否会被重新创建呢?

\n
\n

是的,可以重新创建初始值,但随后它会被忽略
\n例如这里:

\n
function Table(props) {\n  // \xe2\x9a\xa0\xef\xb8\x8f someFunc() is called on every render\n  // But after first (or maybe second render if it is strict mode) it\'s value is ignored\n  const rows = useRef(someFunc(props.count));\n  // ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n

它与类似useState,如果您将一个值传递给其构造函数,它会被重新计算,但随后会被丢弃。您可以传递useState只执行一次的函数。显然根据文档,useRef没有这样的选项。但你可以模拟它:

\n
const ref = useRef(null);\n\n// \xe2\x9c\x85 IntersectionObserver is created lazily once\nfunction getObserver() {\n  if (ref.current === null) {\n    ref.current = new IntersectionObserver(onIntersect);\n  }\n  return ref.current;\n}\n
Run Code Online (Sandbox Code Playgroud)\n