Предпосылка — родительский компонент отображает дочерние компоненты на основе некоторого локального состояния, и мы хотим прокрутить до первого из этих вновь отображаемых дочерних компонентов.
TLDR: Вот ссылка на codeandbox.
См. ниже родительский компонент — прямо сейчас он делает все, кроме части прокрутки. В нем есть кнопка «Добавить элементы», которая — при нажатии — добавляет еще 10 элементов в существующее состояние предметов:
Для этого нам нужны две важные части информации:
- Индекс первого из этих вновь добавленных элементов
- Тот факт, что элемент, к которому мы хотим прокрутить, смонтировался
Индекс отслеживания первого добавленного элемента
Для этого мы будем использовать хук useRef
, который дает переменную экземпляра, которую мы можем использовать для хранения значений между рендерингами. Затем, когда мы добавим новости в переменную состояния items
, мы измерим длину previousItems
, которую мы получим в качестве аргумента в функции обратного вызова, которую мы передаем в setItems
. Если мы добавим к этой длине +1
, мы получим индекс первого недавно добавленного элемента:
Прокрутите до нового элемента на креплении
Чтобы прокрутить до элемента, нам на самом деле нужно разбить element
, который мы отображаем для каждого элемента в состоянии items
, и нам нужно сделать это, потому что нам нужно подключиться к его собственному жизненному циклу, т. е. отслеживать, когда он монтируется.
Компонент считается смонтированным, когда он добавляется в настоящий DOM (вы можете увидеть это, когда откроете инструменты разработки и найдете узел dom, представляющий этот компонент, на вкладке «Элементы»).
В компонентах на основе классов мы бы использовали метод жизненного цикла componentDidMount
, но в мире хуков дочерний компонент, который отображает элемент, будет выглядеть так:
При рендеринге items
нам нужно каким-то образом сообщить первому «новому» экземпляру дочернего компонента, до которого следует прокручивать область просмотра. Для этого мы передадим shouldScrollTo
следующим образом:
Здесь мы просто сравниваем, имеет ли элемент, который мы визуализируем, тот же index
, что и firstNewItemIndex
, чтобы сообщить этому экземпляру Child
, к которому он должен быть прокручен после того, как он имеет mounted
.
Наконец, нам нужно использовать shouldScrollTo
для прокрутки, и мы делаем это следующим образом:
И вот что у нас есть — теперь каждый раз, когда добавляются новые элементы, приложение автоматически прокручивается до первого в самом последнем добавленном наборе.