Предпосылка — родительский компонент отображает дочерние компоненты на основе некоторого локального состояния, и мы хотим прокрутить до первого из этих вновь отображаемых дочерних компонентов.

TLDR: Вот ссылка на codeandbox.

См. ниже родительский компонент — прямо сейчас он делает все, кроме части прокрутки. В нем есть кнопка «Добавить элементы», которая — при нажатии — добавляет еще 10 элементов в существующее состояние предметов:

Для этого нам нужны две важные части информации:

  1. Индекс первого из этих вновь добавленных элементов
  2. Тот факт, что элемент, к которому мы хотим прокрутить, смонтировался

Индекс отслеживания первого добавленного элемента

Для этого мы будем использовать хук useRef, который дает переменную экземпляра, которую мы можем использовать для хранения значений между рендерингами. Затем, когда мы добавим новости в переменную состояния items, мы измерим длину previousItems, которую мы получим в качестве аргумента в функции обратного вызова, которую мы передаем в setItems. Если мы добавим к этой длине +1, мы получим индекс первого недавно добавленного элемента:

Прокрутите до нового элемента на креплении

Чтобы прокрутить до элемента, нам на самом деле нужно разбить element, который мы отображаем для каждого элемента в состоянии items, и нам нужно сделать это, потому что нам нужно подключиться к его собственному жизненному циклу, т. е. отслеживать, когда он монтируется.

Компонент считается смонтированным, когда он добавляется в настоящий DOM (вы можете увидеть это, когда откроете инструменты разработки и найдете узел dom, представляющий этот компонент, на вкладке «Элементы»).

В компонентах на основе классов мы бы использовали метод жизненного цикла componentDidMount, но в мире хуков дочерний компонент, который отображает элемент, будет выглядеть так:

При рендеринге items нам нужно каким-то образом сообщить первому «новому» экземпляру дочернего компонента, до которого следует прокручивать область просмотра. Для этого мы передадим shouldScrollTo следующим образом:

Здесь мы просто сравниваем, имеет ли элемент, который мы визуализируем, тот же index, что и firstNewItemIndex, чтобы сообщить этому экземпляру Child, к которому он должен быть прокручен после того, как он имеет mounted.

Наконец, нам нужно использовать shouldScrollTo для прокрутки, и мы делаем это следующим образом:

И вот что у нас есть — теперь каждый раз, когда добавляются новые элементы, приложение автоматически прокручивается до первого в самом последнем добавленном наборе.