Как реализовать восстановление прокрутки для React Router SPA

11

Я создаю одностраничное приложение React и заметил, что восстановление прокрутки не работает должным образом в Chrome (и, возможно, в других браузерах).

На GitHub-репо реакции-router-dom у них есть страница, на которой говорится, что браузеры начинают обрабатывать прокрутку для одностраничных приложений, и поведение будет аналогичным традиционному веб-сайту, не относящемуся к SPA, если для history.scrollRestorationнего установлено значение auto,

Поведение, которое мне нужно, указано на этой странице:

  1. Прокрутка вверх по навигации, чтобы вы не запустили новый экран, прокручиваемый вниз.
  2. Восстановление позиций прокрутки окна и элементов переполнения при нажатии «назад» и «вперед» (но не при нажатии ссылки!)

Но мне также нужно отключить поведение для маршрутов, которые содержат вкладки или карусель.

Вот ссылка на спецификацию Chrome по этому вопросу .

То, что я наблюдаю в Chrome версии 78.0.3904.97 (Официальная сборка) (64-разрядная версия) для OS X, - это то, что я ожидаю от history.scrollRestoration manualнастроек. То есть, когда я прокручиваюсь на полпути вниз по странице и нажимаю на ссылку, следующая страница прокручивается на полпути вниз до той же точки, что и предыдущая страница.

Я проверил history.scrollRestorationв разных точках и обнаружил, что он запускается и остается auto, по умолчанию,

Одним из важных моментов здесь является ответ @ TrevorRobinson «браузерные автоматические попытки восстановления прокрутки ... ... в основном не работают для одностраничных приложений ..." Хорошо ... Я нашел последовательную поддержку history.scrollRestoration, но по-видимому, браузеры дерьмовые на самом деле делать восстановление прокрутки. Тогда это должно быть отмечено здесь , что сэкономило бы мне время сегодня.

Затем я ищу способы сделать это вручную, и мне не ясно, как двигаться дальше. react-router-scrollговорит, что он не совместим с React Router v4, но не упоминает v5, которая актуальна на данный момент. Так стоит ли предполагать, что v5 тоже не совместим?

Поэтому я продолжаю искать дальнейшие действия и нашел этот SO-ответ о том, как обрабатывать восстановление прокрутки с помощью React Router v4 ... Должен ли я предполагать, что это будет работать с React Router v5? Обновление: это не работает для меня в v5. Я пробовал несколько конфигураций. Я также не мог заставить его полностью работать с React Router v4. Я знал, что оно ожило, по крайней мере, так как оно прокручивается вверх на новой странице, но восстановление в истории не происходит.

Я также установил работоспособность response-router-scroll-memory , но у нее нет опций для отключения прокрутки на назначенных маршрутах, например, что потребуется для вкладок или карусели ... Я мог бы просто взломать ее, чтобы она заработала.

Я рассмотрел возможность использования oaf-реагирующий маршрутизатор , но в документации ничего не говорится об отключении восстановления прокрутки или прокрутки вверх для определенных маршрутов. Изменить: Это действительно обрабатывает это, как изложено в моем ответе.

Есть что-то, что я упустил? Каков стандарт для решения этой проблемы, потому что я не могу быть единственным, кому нужна эта функция. Кажется, я делаю что-то резкое и экспериментальное, но мне просто нужно, чтобы мой сайт прокручивался как обычный сайт.

BBaysinger
источник
2
Вы должны взглянуть на Nextjs , они реализовали это путем кэширования истории.
Jurrian
Круто! Я посмотрю поближе, когда смогу выйти из этого проекта.
BBaysinger

Ответы:

4

Один из способов сделать это - oaf-реагировать на маршрутизатор . Используйте shouldHandleActionпараметры в настройках. Функция передается previousLocationи nextLocationкоторую вы можете использовать для определения необходимости сброса / восстановления прокрутки и возврата, falseесли нет.

const history = createBrowserHistory();

const settings = {
   shouldHandleAction: (previousLocation, nextLocation) => {
       // Inspect/compare nextLocation and/or previousLocation.
       return false // false if you don't want scroll restoration.
   }
};

wrapHistory(history, settings);

oaf-реагирующий маршрутизатор работает с React Router v4 и v5 и обрабатывает специальные возможности, в отличие от многих SPA-маршрутизаторов, поэтому это может быть наиболее полным решением на данный момент.

Любопытно, что документация не раскрывает эту функцию.

Если у кого-то еще есть решение, которое работает и будет считаться более стандартным, предоставьте здесь ответ, и я рассмотрю вопрос об изменении выбранного ответа.

BBaysinger
источник