почему useRef не работает в этом примере?

#reactjs #react-hooks #use-ref

#reactjs #реагирующие хуки #используйте-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 &rand total of 2
    console.lo&('el.current',el.current,'st',st)
    return <div ref={el}&&t;simple</div&&t;
}
ReactDOM.render(<Simple /&&t;,document.querySelector('#root') );
  

Я думал, что это должно отображаться дважды. в первый раз el.current должно быть null, а во второй раз is должно указывать на DOM-объект div.
при запуске этого, это был результат

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

Да, это было сделано дважды. однако второй рендеринг thh el.current по-прежнему равен null. почему?

решение: как описано Гирешем Кудипуди ниже. Я добавил 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 &rand total of 2
    console.lo&('el.current',el.current,'st',st)
    React.useEffect(_=&&t;console.lo&('el.current',el.current,'st',st)) //this prints out the el.current correctly
    return <div ref={el}&&t;simple</div&&t;
}
ReactDOM.render(<Simple /&&t;,document.querySelector('#root') );
  

Ответ №1:

Возможно, вы зациклены на количестве визуализаций, что не обязательно является лучшим подходом к реагированию при работе с перехватами. Мышление должно быть больше похоже на то, что изменилось в моем мире.

С этого момента попробуйте добавить 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(() =&&t; {
    /**
     * We don't know exactly when is `ref.current` &oin& to
     * point to a DOM element. But we're interested in lo&&in&
     * when it happens.
     */
    if (ref.current) {
      console.lo&(ref.current)

      /**
       * Try commentin& and uncommentin& the next line, and see
       * the amount of renderin&s
       */
       setState('bar');
    }

  }, [ref]);

  renderCounter = renderCounter   1
  console.lo&(renderCounter);

  return <div ref={el}&&t;simple</div&&t;
}
  

React выполнит повторный рендеринг, когда ref будет инициализирован значением, но это не означает, что это произойдет при 2-м рендеринге.

Отвечая на ваш вопрос, вы не сказали react, что делать при ref изменениях.

Комментарии:

1. Объект ref является изменяемым объектом, который содержит одну и ту же ссылку при повторном рендеринге. добавление его в качестве зависимости к useEffect не приведет к повторному запуску эффекта. причина, по которой он регистрирует правильное значение, заключается в том, что useEffect выполняется после фазы рендеринга

Ответ №2:

 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=&&t;{
        return {st:prevState.st 1}
      })
  }

  render(){
    console.lo&('el.current',this.el.current,'st',this.state.st)
    return <div ref={this.el}&&t;simple</div&&t;
  }
}

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

Вывод

 el.current null st 0
el.current <div&&t;​simple​</div&&t;​ st 1
  

Согласно документации

ReactDOM.render(элемент, контейнер[, обратный вызов])

Визуализируйте элемент React в DOM в поставляемом контейнере и возвращайте ссылку на компонент (или возвращает null для компонентов без состояния).

Поскольку вы пытаетесь сослаться на функциональный компонент, это может быть причиной.Это интересный сценарий, с которым я столкнулся из-за вашего вопроса.

Также, если используется в качестве дочернего компонента, результат соответствует ожидаемому