1. Введение
useRef
это обычный API, но есть еще одинcreateRef
API, вы знаете разницу между ними? пройти черезReact.useRef and React.createRef: The DifferenceВ этой статье вы можете узнать, когда их использовать.
2 Обзор
Фактически, в оригинальном тексте говорится об этом факте:useRef
Может использоваться только в FunctionComponent,createRef
Может использоваться только в ClassComponent.
Первое предложение очевидно, потому что хуки нельзя использовать в ClassComponent.
Причина второго предложения заключается в том,createRef
Эффекта Hooks нет, и его значение постоянно инициализируется по мере многократного выполнения FunctionComponent:
function App() {
// 错误用法,永远也拿不到 ref
const valueRef = React.createRef();
return <div ref={valueRef} />;
}
вышесказанноеvalueRef
Он будет неоднократно инициализироваться с помощью функции Render of the App,В этом также заключается уникальность хуков, хотя они и используются в обычных функциях, но в движке React они будут выполнять не только обычные функции, например, инициализация выполняется только один раз, либо ссылка остается неизменной..
ЗачемcreateRef
Может ли он нормально работать в ClassComponent? Это связано с тем, что ClassComponent разделяет жизненный цикл, делая, например,componentDidMount
Подождите, пока время инициализации выполнится только один раз.
Исходный текст закончился.
3 Интенсивное чтение
Итак, теперь, когда вы знаете, как правильно создать ссылку, знаете ли вы также, как правильно обновить ссылку?
Поскольку Ref является экземпляром во всех циклах рендеринга FunctionComponent, теоретически его можно изменить где угодно, например:
function App() {
const valueRef = React.useRef();
valueRef.current += 1;
return <div />;
}
Но на самом деле указанный выше метод модификации не стандартизирован. Официальный документ React требует от нас избегать прямого изменения Ref в функции Render. См. следующую диаграмму жизненного цикла FunctionComponent:
Из рисунка видно, что вRender phase
Фазам не разрешается делать «побочные эффекты», то есть писать код побочных эффектов, потому что эта фаза может быть отменена или переделана движком React в любое время.
Модификация Ref является побочной операцией, поэтому ее нельзя выполнять на данном этапе. Мы можем видеть это вCommit phase
Это могут делать фазы или обратные вызовы (вне жизненного цикла React).
Конечно, есть ситуация, когда это возможно, а именноленивая инициализация:
function Image(props) {
const ref = useRef(null);
// ✅ IntersectionObserver is created lazily once
function getObserver() {
if (ref.current === null) {
ref.current = new IntersectionObserver(onIntersect);
}
return ref.current;
}
// When you need it, call getObserver()
// ...
}
В случае ленивой инициализации побочные эффекты выполняются не более одного раза и используются только для инициализации присваиваний, поэтому такое поведение разрешено.
Почему существуют такие строгие ограничения на побочные эффекты? Поскольку в FunctionComponent добавлена встроенная система планирования, чтобы дать приоритет реагированию на действия пользователя, рендеринг компонента React может быть временно запланирован.Подробности см. в 99-м интенсивном чтении:Интенсивное чтение "Планирование в React"
Ref может не только получать ссылки на компоненты, создавать объект побочного эффекта Mutable, но и взаимодействовать сuseEffect
Сохраняет более старое значение, чаще всего используемое для полученияpreviousProps
, React официально использует Ref для инкапсуляции простых хуков для получения последнего значения:
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
из-заuseEffect
Выполняется после завершения рендеринга, поэтомуref
Значение всегда является последним рендером в текущем рендере, мы можем использовать его для получения последних реквизитов:
function App(props) {
const preProps = usePrevious(props);
}
Для достижения этой функции, по-прежнему благодаряref
Значения могут быть «свойствами, переданными в различных замыканиях Render». Наконец, не злоупотребляйте Refs, чем больше ссылок на Mutable у вас есть, тем менее удобным будет их сопровождение для React.
4 Резюме
ты тоже копалuseRef
Какие есть интересные способы его использования? Добро пожаловать, чтобы оставить сообщение в области комментариев.
Адрес обсуждения:Интенсивное чтение «Разница между useRef и createRef» · Выпуск №236 · dt-fe/weekly
Если вы хотите принять участие в обсуждении, пожалуйста,кликните сюда, с новыми темами каждую неделю, выходящими по выходным или понедельникам. Интерфейс интенсивного чтения — поможет вам отфильтровать надежный контент.
Сфокусируйся наАккаунт WeChat для интенсивного чтения в интерфейсе
Заявление об авторских правах: Бесплатная перепечатка - некоммерческая - не производная - сохранить авторство (Лицензия Creative Commons 3.0)