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

时间:2020-08-07 21:39:43

标签: reactjs react-hooks use-ref

这是我的react hooks代码:

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

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

el.current null st 0
el.current null st 1

是的,它渲染了两次。但是,第二个渲染当前电流仍为空。为什么?

解决方案:如下文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') );

2 个答案:

答案 0 :(得分:3)

可能是您已经固定在渲染量上,这不一定是使用钩子时最好的React心态。心态应该更像我的世界发生了什么变化

从那时起,尝试添加一个useEffect并告诉您您有兴趣了解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>
}

ref用一个值初始化后,React将重新渲染,但这并不意味着它将在第二个渲染上发生。

要回答您的问题,您没有告诉自己ref更改后该怎么做。

答案 1 :(得分:0)

class SimpleComponent extends React.Component{
  el = React.createRef(null)
  constructor(props){
    super(props)
    this.state = {
      st:0
    }
  }
  componentDidMount(){
    if(this.state.st<1)
      this.setState(prevState=>{
        return {st:prevState.st+1}
      })
  }

  render(){
    console.log('el.current',this.el.current,'st',this.state.st)
    return <div ref={this.el}>simple</div>
  }
}

ReactDOM.render(<SimpleComponent />,document.querySelector('#root') );

输出为

el.current null st 0
el.current <div>​simple​</div>​ st 1

根据Documentation

ReactDOM.render(element,container [,callback])

在提供的容器中的DOM中渲染一个React元素,并返回对该组件的引用(或对于无状态组件,返回null )。

由于您尝试引用功能组件,这可能是原因。由于您的问题,我遇到了一个有趣的场景。

如果用作子组件,输出也将符合预期