#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 для компонентов без состояния).
Поскольку вы пытаетесь сослаться на функциональный компонент, это может быть причиной.Это интересный сценарий, с которым я столкнулся из-за вашего вопроса.
Также, если используется в качестве дочернего компонента, результат соответствует ожидаемому