React Hooks:useRef Hook为什么.current为null?

Xen*_*mar 8 reactjs react-hooks

我有一个简单的组件示例:

function App() {
  const observed = useRef(null);
  console.log(observed.current);

  return (
    <div ref={observed} className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Run Code Online (Sandbox Code Playgroud)

我希望它observed.current的类型为element,而current不会为空,而是具有所有属性的div元素。我的理解是:

  1. 引用初始化为空值
  2. 引用将覆盖Null

但事实证明,.current仍然是空的。这很不好,因为我想将观察值传递给需要Element类型参数的函数。

https://codesandbox.io/embed/purple-forest-0460k

小智 15

console.log发生时,ref尚未设置。尝试将您console.loguseEffect钩子放入钩子中,它会按您的意愿工作。

import React, { useRef, useEffect } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  const observed = useRef(null);

  useEffect(() => {
    console.log(observed.current);
  }, [observed]);

  return (
    <div ref={observed} className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Run Code Online (Sandbox Code Playgroud)

  • 为什么这会起作用?`observed` 是一个 Ref,因此不会触发任何重新运行。因此,如果代码的其他部分不会触发重新渲染,则 Ref 将始终保持为空,直到某些内容重新渲染为止。 (4认同)

Avi*_*ish 9

Ref.current为null,因为直到函数返回并呈现内容后才设置ref。所述useEffect钩触发间隔的阵列的内容的值传递给它的变化的时间。通过传入observed数组并传递记录observed到控制台的回调,可以利用useEffect挂钩完成任务。

  useEffect(() => {
    console.log(observed.current);
  }, [observed]);
Run Code Online (Sandbox Code Playgroud)

代码沙箱

  • 我认为 useEffect 只会运行一次,因为即使observed.current发生变化,observed也永远不会改变。这就是 useRef 的要点。“返回的对象将在组件的整个生命周期中持续存在。” https://codesandbox.io/s/romantic-tharp-dsnpx (6认同)
  • _“您必须检查 `useEffect` 钩子中的值”_ - 这个语句不是_严格_正确的,我可以有一个可以访问 ref 的记忆回调函数。主要的一点是 ref 为空,因为 UI 还没有真正渲染,`useEffect` 在这里工作是因为 `useEffect` 它相当于 `componentDidMount` 和其他一些运行 _after_ 组件渲染的钩子。 (2认同)
  • 在我看来,使用 refs 作为 useEffect() 依赖项是一种反模式。未来对 ref.current 的任何更改都不会触发 useEffect()。 (2认同)

tsu*_*suz 8

这是我最后呼吁以来做useEffectrlvRef没有捕获所有事件。

const rlvRef = useRef()
const [refVisible, setRefVisible] = useState(false)

useEffect(() => {
  if (!refVisible) { 
    return
  }
  // detected rendering
}, refVisible)

return (
  <RecyclerListView
    ref={el => { rlvRef.current = el; setRefVisible(!!el); }}
    ... 
  />
)
Run Code Online (Sandbox Code Playgroud)

  • 无法分配给“当前”,因为它是只读属性 (6认同)
  • 不,`rlvRef.current` 不是只读值。该引用是“const”,但“.current”是可变的。 (5认同)
  • 任何人都会遇到这个问题:在 Typescript 中,尝试: `useRef&lt;HTMLDivElement | null&gt;(null)` (如果元素是 `&lt;div&gt;`)。奇怪的是,添加`| null` 类型修复了错误。 (3认同)