Спасибо Альваро за разъяснение вопроса. Я хочу объяснить, где мое мышление пошло не так, если предположить, что я не единственный, кто совершил эту ошибку.
Мои плохие логи c
Мы используем effect
крючки, потому что код изменяет DOM, и useEffect
существует для обработки именно такого рода побочных эффектов.
Мы используем ref
перехватчики для соединения с данным элементом DOM. Экземпляр ref
похож на одноэлементный, в этом случае экземпляр не изменяется в течение жизни приложения. Изменяется только свойство ref.current
.
И непосредственно под соответствующим разделом в справочных документах о перехватах Я прочитал это:
Имейте в виду, что useRef не не уведомит вас, когда его содержание изменится. Отключение свойства .current
не вызывает повторного рендеринга.
После этого я понял, что соответствующие зависимости должны быть переданы в вызов useEffect
. И то, что элемент для обновления (в ref.current
) был одной из этих зависимостей. И поскольку изменение свойства ref.current
не вызывает повторного рендеринга, оно, по-видимому, тоже не инициировало вызов useEffect
.
Кстати: это мышление было подкреплено es-lint
с требованием добавить ref.current
(в моем случае div = ref.current
) в списке зависимостей: React Hook useEffect has a missing dependency: 'div'. Either include it or remove the dependency array.
Я всегда доверяю линтеру, конечно.
Мой вывод: не было простого способа использовать effect
ловушку для сделать в ref
экземпляр. Мне нужно было как-то поместить ref.current
в useState
сеттер. Ужасно!
Мое основное предположение
Я предположил, что способ useEffect
обрабатывать побочные эффекты не имеет значения. Крюк effect
- это черный ящик, скрытый в недрах исходного кода typescript
, и он движется таинственными способами.
Но единственное, что «похоронили», было это предложение в use-effect docs :
Функция, переданная useEffect, запустится после фиксации рендера на экране.
" После рендер ». Конечно. То есть как useEffect
обрабатывает побочные эффекты, гарантируя, что не будет работать, пока DOM не будет готов к go.
Решение
Как следует из ответа Альваро Обязательно прочитайте свойство ref.current
внутри useEffect
hook. ref
никогда не меняется, и ref.current
гарантированно будет уже заполнен элементом DOM.
Как обычно, это очевидно задним числом. Еще раз спасибо, Альваро.