React Hooks: Почему.current null для useRef Hooks?
У меня есть простой пример компонента:
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
будет иметь тип элемента и текущий не будет пустым, но элемент div со всеми его свойствами. Мое понимание будет:
- Ссылка инициализируется значением null
- Null перезаписывается ссылкой
Но, как оказалось, .current
остается пустым. Это плохо, так как я хочу передать наблюдаемое в функцию, которая ожидает аргумент типа Element.
4 ответа
Ref.current
является нулевым, потому что ссылка не устанавливается до тех пор, пока функция не вернется и содержимое будет отображено. Хук useEffect срабатывает каждый раз, когда изменяется значение содержимого переданного ему массива. Мимоходом observed
в массиве и путем передачи обратного вызова, который регистрирует observed
к консоли можно использовать хук useEffect для выполнения вашей задачи.
useEffect(() => {
console.log(observed.current);
}, [observed]);
Это то, чем я закончил с тех пор, как позвонил useEffect
на rlvRef
не охватил все события.
const rlvRef = useRef()
const [refVisible, setRefVisible] = useState(false)
useEffect(() => {
if (!refVisible) {
return
}
// detected rendering
}, refVisible)
return (
<RecyclerListView
ref={el => { rlvRef.current = el; setRefVisible(!!el); }}
... />
)
В то время console.log
случается, ref
еще не установлен. Попробуйте положить свой console.log
в useEffect
крючок, и он работает так, как вы хотите.
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);
Мне нужно было установить значение в переменную useRef(), которая была получена асинхронным http-запросом и сохранена в переменной useState(). Поэтому мне нужно было предоставить его как зависимость в функции useEffect():
const [object, setObject] = useState('');
const fetchObject = useCallback(async () => {
const res = await fetch(apiUrl + "/object/", {});
setObject({ ...await res.json() });
}, [apiUrl]);
const jsonEditor = React.createRef();
useEffect(() => {
fetchObject();
if (jsonEditor.current && object.json) {
jsonEditor.current.jsonEditor.set(JSON.parse(object.json));
}
}, [fetchObject, object.json]);
return (
<div>
<JsonEditor
ref={jsonEditor}
onChangeText={onChangeTextHandler}
/>
</div>);