Jak zaimplementować przywracanie zwoju dla React Router SPA

11

Tworzę jednostronicową aplikację React i zauważyłem, że przywracanie przewijania nie działa zgodnie z oczekiwaniami w Chrome (i może w innych przeglądarkach).

W repozytorium reag-router-dom github mają stronę z informacją, że przeglądarki zaczynają natywnie obsługiwać przewijanie dla aplikacji na pojedynczych stronach, a zachowanie byłoby podobne do działania tradycyjnej strony internetowej innej niż SPA, jeśli history.scrollRestorationjest ustawione na auto.

Zachowanie, którego potrzebuję, jest wskazane na tej stronie:

  1. Przewijanie w górę, aby nie rozpocząć nowego ekranu przewiniętego w dół.
  2. Przywracanie pozycji przewijania okna i elementów przepełnienia dla kliknięć „wstecz” i „do przodu” (ale nie kliknięć łącza!)

Ale muszę też wyłączyć zachowanie tras zawierających tabulatory lub karuzelę.

Oto link do specyfikacji Chrome dotyczącej problemu .

To, co obserwuję w wersji Chrome 78.0.3904.97 (oficjalna wersja) (wersja 64-bitowa) dla systemu OS X, wydaje się być tym, czego oczekiwałbym od tego history.scrollRestoration manualustawienia. Oznacza to, że kiedy przewijam się w połowie strony i klikam łącze, następna strona jest przewijana w połowie strony, do tego samego miejsca, co poprzednia strona.

Sprawdziłem history.scrollRestorationróżne punkty i okazało się, że zaczyna się i pozostaje auto, domyślnie,

Jednym z ważnych punktów jest odpowiedź @ TrevorRobinson na „automatyczne próby przywrócenia zwoju przez przeglądarkę… ... przeważnie nie działają w przypadku aplikacji jednostronicowych…” Ok… Znalazłem spójne wsparcie history.scrollRestoration, ale Najwyraźniej przeglądarki są kiepskie w DOKONYWANIU przywracania zwoju. Należy to tutaj zauważyć , co zaoszczędziłoby mi dzisiaj czasu.

Następnie szukam sposobów na zrobienie tego ręcznie i nie jestem pewien, jak postąpić dalej. react-router-scrollmówi, że nie jest kompatybilny z React Router v4, ale nie wspomina o wersji 5, która jest aktualna od tego pytania. Więc czy należy założyć, że wersja 5 również nie jest kompatybilna?

Rozglądam się więc dalej i znalazłem odpowiedź SO na temat obsługi przywracania przewijania za pomocą React Router v4 ... Czy powinienem założyć, że będzie działać z React Router v5?Aktualizacja: Wygląda na to, że nie działa dla mnie w wersji 5. Wypróbowałem kilka konfiguracji. Nie mogłem też całkowicie uruchomić go z React Router v4. Wiedziałem, że przynajmniej ożył, ponieważ przewija się do góry na nowej stronie, ale przywrócenie historii nie następuje.

Dostałem też pamięć przewijania routera reagującego działającą , ale nie ma opcji wyłączania przewijania na wyznaczonych trasach, takich jak te, które byłyby potrzebne do kart lub karuzeli ... Mógłbym po prostu zhakować go, aby działał.

Zastanawiałem się nad użyciem oaf-reagującego routera , ale w dokumentacji nic nie mówi o wyłączeniu przywracania przewijania lub przewijaniu do góry dla niektórych tras. Edycja: Naprawdę to obsługuje, jak opisano w mojej odpowiedzi.

Czy jest coś, co przeoczyłem? Jaki jest standard radzenia sobie z tym problemem, ponieważ nie mogę być jedynym, który potrzebuje tej funkcji. Wygląda na to, że robię coś nerwowego i eksperymentalnego, ale po prostu potrzebuję, aby moja strona przewijała się jak normalna strona.

BBaysinger
źródło
2
Powinieneś rzucić okiem na Nextjs , zaimplementowali to poprzez buforowanie historii.
Jurrian
Fajne! Przyjrzę się bliżej, kiedy będę mógł zejść z tego projektu.
BBaysinger

Odpowiedzi:

4

Jednym ze sposobów jest skorzystanie z routera oaf-React-Router . Skorzystaj z shouldHandleActionopcji w ustawieniach. Funkcja zostaje przekazana previousLocationi nextLocationmożna jej użyć do ustalenia, czy przewijanie powinno zostać zresetowane / przywrócone, i wróć, falsejeśli nie.

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-reag-router współpracuje z React Router v4 i v5 i obsługuje dostępność, w przypadku gdy wiele routerów SPA tego nie robi, więc może być to obecnie najbardziej kompletne rozwiązanie.

Co ciekawe, dokumentacja nie opisuje szczegółowo tej funkcji.

Jeśli ktokolwiek ma rozwiązanie, które działa i byłoby uważane za bardziej standardowe, proszę podać odpowiedź tutaj, a ja rozważę zmianę wybranej odpowiedzi.

BBaysinger
źródło