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

IT技术 reactjs react-hooks
2021-04-13 08:25:55

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

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是 element 类型的,current 不会是空的,而是具有所有属性的 div 元素。我的理解是:

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

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

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

3个回答

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

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

编辑:这仅适用于第一次渲染,因为对 ref 的更改不会触发重新渲染。但是关于 useEffect 的一般说法仍然成立。如果你想观察一个 dom 元素的 ref 的变化,你可以使用回调作为 ref。

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

代码沙盒

万分谢意!我对 Hooks 非常了解,但对于功能组件,我会假设整个功能是“渲染功能”。您是否可以参考我在渲染函数中可以做和不能做的事情?
2021-06-07 08:25:55
@Jame 更改了文本,对于未来的读者来说应该更清楚。reactjs.org/docs/hooks-reference.html#usememo
2021-06-07 08:25:55
@AvinKavish 编辑看起来好多了 IMO :) Xen_mar 检查useCallback
2021-06-08 08:25:55
“你必须检查useEffect钩子内的值 ——这个陈述不是严格正确的,我可以有一个可以访问引用的记忆回调函数。主要的一点是 ref 为空,因为 UI 还没有真正呈现,useEffect在这里工作是因为useEffect它等效于在组件呈现componentDidMount运行的其他一些钩子
2021-06-17 08:25:55
我认为 useEffect 只会运行一次,因为即使 Observed.current 发生变化,observed 也永远不会改变。这就是 useRef 的重点。“返回的对象将在组件的整个生命周期内持续存在。” codeandbox.io/s/romantic-tharp-dsnpx
2021-06-21 08:25:55

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

这是我最后呼吁以来做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); }}
    ... 
  />
)
无法分配给“当前”,因为它是只读属性
2021-06-06 08:25:55
像魅力一样工作。其他答案都不适合我。
2021-06-10 08:25:55