React Hooks:为什么 useRef Hook 的 .current 为空?

React Hooks: Why is .current null for useRef Hook?

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

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);

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

  1. ref 初始化为 null
  2. Null 被 ref 覆盖

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

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

Ref.current 为空,因为在函数 returns 之后才设置 ref 并呈现内容。每当传递给它的数组内容的值发生变化时,useEffect 钩子就会触发。通过在数组中传递 observed 并将记录 observed 的回调传递到控制台,可以利用 useEffect 挂钩来完成您的任务。

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

编辑:这仅适用于第一次渲染,因为对 ref 的更改不会触发 re-renders。但关于 useEffect 的一般说法仍然成立。如果你想观察 dom 元素的 ref 的变化,你可以使用 callback as ref.

  <div 
    ref={el => { console.log(el); observed.current = el; }} // or setState(el)
    className="App"
  >

Code Sandbox

console.log 发生时,ref 尚未设置。尝试将您的 console.log 放入 useEffect 挂钩中,它会按您希望的那样工作。

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);

这就是我最终做的事情,因为在 rlvRef 上调用 useEffect 没有捕获所有事件。

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

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

return (
  <RecyclerListView
    ref={el => { rlvRef.current = el; setRefVisible(!!el); }}
    ... 
  />
)