为什么 useRef 在此示例中不起作用?

yig*_*gal 2 reactjs react-hooks use-ref

这是我的反应钩子代码:

function Simple(){
    var [st,set_st]=React.useState(0)
    var el=React.useRef(null)
    if (st<1)
        set_st(st+1)//to force an extra render for a grand total of 2
    console.log('el.current',el.current,'st',st)
    return <div ref={el}>simple</div>
}
ReactDOM.render(<Simple />,document.querySelector('#root') );
Run Code Online (Sandbox Code Playgroud)

我认为它应该渲染两次。第一次 el.current 应该为 null,第二次应该指向 div 的 DOM 对象。运行它时,这是输出

el.current null st 0
el.current null st 1
Run Code Online (Sandbox Code Playgroud)

是的,它确实渲染了两次。但是,第二次渲染 el.current 仍然为空。为什么?

解决方案:如下 Gireesh Kudipudi 所描述。我添加了useEffect

function Simple(){
    var [st,set_st]=React.useState(0)
    var el=React.useRef(null)
    if (st<1)
        set_st(st+1)//to force an extra render for a grand total of 2
    console.log('el.current',el.current,'st',st)
    React.useEffect(_=>console.log('el.current',el.current,'st',st)) //this prints out the el.current correctly
    return <div ref={el}>simple</div>
}
ReactDOM.render(<Simple />,document.querySelector('#root') );
Run Code Online (Sandbox Code Playgroud)

Chr*_*sco 5

可能您专注于渲染量,这不一定是使用 hooks 时最好的 React 心态。心态应该更像我的世界发生的变化

从那时起,尝试添加 auseEffect并告诉它您有兴趣查看ref我的世界何时发生变化。尝试以下示例,并亲自查看行为。

let renderCounter = 0;

function Simple() {
  const [state, setState] = useState()
  const ref = React.useRef(null)

  if (state < 1) {
    /** 
     * We know this alter the state, so a re-render will happen
     */
    setState('foo')
  }

  useEffect(() => {
    /**
     * We don't know exactly when is `ref.current` going to
     * point to a DOM element. But we're interested in logging
     * when it happens.
     */
    if (ref.current) {
      console.log(ref.current)

      /**
       * Try commenting and uncommenting the next line, and see
       * the amount of renderings
       */
       setState('bar');
    }

  }, [ref]);

  renderCounter = renderCounter + 1
  console.log(renderCounter);

  return <div ref={el}>simple</div>
}
Run Code Online (Sandbox Code Playgroud)

当使用值初始化时,React 将重新渲染ref,但这并不意味着它会在第二次渲染时发生。

为了回答你的问题,你还没有告诉反应发生变化时要做什么ref

  • ref 对象是一个可变对象,在重新渲染时保存相同的引用。将其作为依赖项添加到 `useEffect` 将不会重新触发效果。它记录正确值的原因是因为“useEffect”在渲染阶段之后运行 (4认同)