#javascript #reactjs #react-native
#javascript #reactjs #react-native
Вопрос:
У меня есть вопрос об объявлении ссылок в React с использованием хука useRef .
Есть ли какая-либо разница между этим:
const inputRef = useRef(null).current;
...
inputRef?.focus();
и это:
const inputRef = useRef(null);
...
inputRef.current?.focus();
??
В моем коде поведение такое же, но в некоторых ситуациях, при других вариантах использования, у меня разные результаты.
Например:
const arrayRef = useRef(null);
arrayRef.current = data; // data is an array of numbers
похоже, это не то же самое, что
const arrayRef = useRef(null).current;
arrayRef = data;
Но почему? (Не совсем уверен, что это не одно и то же, но мой код неожиданно работает с использованием второго метода.)
Я был бы очень признателен за вашу помощь. Спасибо.
Комментарии:
1. Это не имеет никакого смысла,
useRef(null).current
потому что вы не можете ничего назначить ссылке (как вы указали)? Показать больше контекста.2. Ссылка — это объект со
current
свойством. Этоcurrent
значение может измениться, и поэтому объект ref является удобной оболочкой вокруг этого изменяющегося значения, поэтому вы можете передавать ССЫЛКУ на значение в своем приложении, а не просто передавать значение. Когда вы используетеcurrent
вместо объекта, вы разворачиваете ссылку, и теперь это просто обычное значение. Если оно изменится, вы можете не получить это изменение везде, где вы используете ссылку, потому что вы ссылаетесь на значение, а не на исходную ссылку. Не разворачивайте его, просто передайте ссылку и используйтеref.current
для доступа к значению, когда вам нужно.3. Есть причина, по которой разработчики в React решили сделать это таким образом. Не нарушайте его.
4. @Raul — хороший! Это особый случай. Сама ссылка в этом компоненте никогда не будет переназначена, а значение, которое она содержит (анимированное значение), обрабатывается с помощью других механизмов.
5. @Raul — учитывается контекст. С учетом контекста становится очень ясно и очевидно, почему код написан именно так.
Ответ №1:
Проблема с использованием .current
заключается в том, что это немедленно извлекает текущую ссылку. Если значение извлекается во время рендеринга, но позже происходит повторный рендеринг, но начальный рендеринг все еще использует где-то извлеченную ссылку, это будет ссылка на старое значение в ссылке, которое может еще не существовать.
Для быстрого примера:
const Foo = () => {
const inputRef = useRef(null);
useEffect(() => {
window.addEventListener('custom-focus-the-input', () => {
inputRef.current.focus();
});
}, []);
return (
<input ref={inputRef} />
);
};
Выше ссылка должна использоваться как обычная ссылка. Вы не можете извлечь его в его current
значение, пока не окажетесь внутри прослушивателя событий, потому что ссылка ссылки изменяется при первом рендеринге.
Кроме того, чтобы ссылка была .current
назначена правильно, вы должны поместить саму ссылку в возвращаемый JSX — не помещайте .current
значение в JSX, потому что это не приведет к изменению .current
свойства ссылки.
В общем случае извлекайте .current
значение из ссылки только до тех пор, пока вам не понадобится использовать его в ближайшее время в последующем синхронном коде.
Ответ №2:
useRef
(как и почти все перехватчики react) эффективно предоставляет переменную экземпляра чему-то, у чего нет экземпляра (функциональный компонент не поддерживается экземпляром — это функция, но react отслеживает его жизненный цикл с помощью fiber и другой классной магии).
Теперь, когда вы знаете, что это просто переменная экземпляра, становится ясно, что переменные экземпляра полезны только в том случае, если им можно что-то назначить.
const animatedOpacity = useRef(new Animated.Value(0)).current;
Переменной экземпляра присваивается Animated.Value
. Его никогда не нужно переназначать, потому Animated.Value
что (который является current
свойством ссылки) обрабатывается / переназначается с помощью других функций, например Animated.timing
.