Właśnie wymieniłem react-router
z v3 na v4.
Ale nie jestem pewien, jak programowo nawigować w funkcji członka Component
. tzn. w handleClick()
funkcji chcę nawigować /path/some/where
po przetworzeniu niektórych danych. Robiłem to przez:
import { browserHistory } from 'react-router'
browserHistory.push('/path/some/where')
Ale nie mogę znaleźć takich interfejsów w wersji 4.
Jak nawigować za pomocą v4?
reactjs
ecmascript-6
react-router-v4
Colin Witkamp
źródło
źródło
Component
? Na przykład wewnątrz akcji redux.Odpowiedzi:
Jeśli celujesz w środowiska przeglądarki, musisz użyć
react-router-dom
pakietu zamiastreact-router
. Stosują to samo podejście, co React, aby oddzielić rdzeń (react
) i kod specyficzny dla platformy, (react-dom
,react-native
) z tą niewielką różnicą, że nie trzeba instalować dwóch oddzielnych pakietów, więc pakiety środowiska zawierają wszystko potrzebujesz. Możesz dodać go do swojego projektu jako:yarn add react-router-dom
lub
npm i react-router-dom
Pierwszą rzeczą, którą musisz zrobić, to podać
<BrowserRouter>
jako najwyższy komponent nadrzędny w swojej aplikacji.<BrowserRouter>
używahistory
interfejsu API HTML5 i zarządza nim za Ciebie, więc nie musisz się martwić o samodzielne tworzenie instancji i przekazywanie jej do<BrowserRouter>
komponentu jako rekwizytu (tak jak to robiłeś w poprzednich wersjach).W wersji 4 do nawigowania programowego potrzebujesz dostępu do
history
obiektu, który jest dostępny przez Reactcontext
, pod warunkiem, że masz komponent<BrowserRouter>
dostawcy jako najwyższy nadrzędny w twojej aplikacji. Biblioteka udostępnia poprzez kontekstrouter
obiekt, który sam zawierahistory
jako właściwość.history
Interfejs oferuje kilka metod nawigacji, takie jakpush
,replace
igoBack
, między innymi. Można sprawdzić całą listę właściwości i metody tutaj .Ważna uwaga dla użytkowników Redux / Mobx
Jeśli używasz w aplikacji aplikacji redux lub mobx, być może natrafiłeś na problemy z komponentami, które powinny rozpoznawać lokalizację, ale nie są renderowane ponownie po uruchomieniu aktualizacji adresu URLDzieje się tak, ponieważ
react-router
przechodzilocation
do komponentów przy użyciu modelu kontekstowego.Dwa podejścia do rozwiązania tego:
<Route />
. Obecnylocation
obiekt jest jednym z rekwizytów<Route>
przekazywanych do renderowanego komponentuwithRouter
wyższego rzędu, który w rzeczywistości ma ten sam efekt i wstrzykujelocation
jak rekwizytPoza tym istnieją cztery sposoby programowej nawigacji, uporządkowane według zaleceń:
1.- Korzystanie z
Promuje deklaratywny styl. Przed wersją v4<Route>
komponentu<Route />
komponenty były umieszczane na szczycie hierarchii komponentów, dlatego należy wcześniej pomyśleć o strukturze tras. Jednak teraz możesz mieć<Route>
komponenty w dowolnym miejscu w drzewie, co pozwala na dokładniejszą kontrolę warunkowego renderowania w zależności od adresu URL.Route
wstrzykujematch
,location
ahistory
jako rekwizyty do swojego komponentu. Metody nawigacji (takie jakpush
,replace
,goBack
...) są dostępne jako właściwościhistory
obiektu.Istnieją 3 sposoby renderowania czegoś
Route
za pomocą albocomponent
,render
albochildren
rekwizytów, ale nie używaj więcej niż jednego w tym samymRoute
. Wybór zależy od przypadku użycia, ale w zasadzie dwie pierwsze opcje renderują komponent tylko wtedy, gdypath
pasuje do lokalizacjichildren
adresu URL , natomiast w przypadku komponentu będzie renderowany, czy ścieżka pasuje do lokalizacji, czy nie (przydatne w dostosowywaniu interfejsu użytkownika na podstawie adresu URL pasujący).Jeśli chcesz, aby dostosować moc renderowania komponentu , należy owinąć komponent w funkcji i użyć
render
opcji, aby przejść do komponentu innych rekwizytów pragnienie, opróczmatch
,location
ihistory
. Przykład ilustrujący:2.- Korzystanie z
withRouter
HoCTen komponent wyższego rzędu wstrzykuje te same rekwizyty co
Route
. Jednak niesie ze sobą ograniczenie, że możesz mieć tylko 1 HoC na plik.3.- Używanie
Renderowanie aRedirect
komponentu<Redirect>
spowoduje przejście do nowej lokalizacji. Należy jednak pamiętać, że domyślnie bieżąca lokalizacja jest zastępowana nową, jak przekierowania po stronie serwera (HTTP 3xx). Nowa lokalizacja jest zapewniona przezto
prop, który może być ciągiem (URL do przekierowania) lublocation
obiektem. Jeśli zamiast tego chcesz wprowadzić nowy wpis do historii ,push
podaj również rekwizyt i ustaw go natrue
4.- Dostęp
Nieco zniechęcony, ponieważ kontekst jest wciąż eksperymentalnym interfejsem API i może ulec zmianie / zmianie w przyszłych wydaniach Reactrouter
ręczny przez kontekstNie trzeba dodawać, że istnieją również inne komponenty routera przeznaczone dla ekosystemów nieobsługujących przeglądarki, takie jak
<NativeRouter>
replikacja stosu nawigacji w pamięci i docelowa platforma React Native, dostępna za pośrednictwemreact-router-native
pakietu.W celu uzyskania dalszych informacji, nie wahaj się rzucić okiem na oficjalne dokumenty . Istnieje również wideo wykonane przez jednego ze współautorów biblioteki, które zapewnia całkiem fajne wprowadzenie do routera reagującego v4, podkreślając niektóre z głównych zmian.
źródło
withRouter
zreact-router-dom
withRouter
zreact-router-dom
. History.push zmienia adres URL, ale wydaje się, że nie ładuje,<Route>
dopóki nie<Router>
wewnątrz dekorowanego komponentu React@observer
, co powoduje ten problem . Around praca ma mieć@withRouter
na każdy taki React komponent.withRouter
jest po prostu HOC, który używaRoute
pod maską. Co oznacza, że używa tylko 3 rekwizytów, historii, dopasowania i lokalizacji . W powyższym przykładzie wydaje się, żepush
jest to rekwizyt,withRouter
który dodałbyButtonToNavigate
, ale tak nie jest.props.history.push
musiałby zostać użyty zamiast tego. Mam nadzieję, że to pomaga innym, którzy byli nieco zdezorientowani.browserHistory.push('/path/some/where')
po prostu wydaje się o wiele prostsze. Autorzy starają się zniechęcić do programowania imperatywnego, ale czasem działa to po prostu lepiej!Najłatwiejszym sposobem, aby to zrobić:
this.props.history.push("/new/url")
Uwaga:
history
prop
nadrzędny do elementu, który chcesz wywołać, jeśli nie jest dostępny.źródło
this.props.history
w swoim komponencie, możesz,import {withRouter} from 'react-router-dom'
a następnieexport default withRouter(MyComponent)
(lubconst MyComponent = withRouter(...)
), a on wstawihistory
element do rekwizytów twojego komponentu.history.push
i po prostu uruchomić aktualizację, tak jak po kliknięciu<Link>
Miałem podobny problem podczas migracji do React-Router v4, więc postaram się wyjaśnić moje rozwiązanie poniżej.
Proszę nie uważać tej odpowiedzi za właściwy sposób rozwiązania problemu, wyobrażam sobie, że istnieje spora szansa, że pojawi się coś lepszego, gdy React Router v4 stanie się bardziej dojrzały i pozostawi wersję beta (może nawet już istnieć, a ja po prostu jej nie odkryłem) .
Dla kontekstu miałem ten problem, ponieważ czasami używam
Redux-Saga
do programowej zmiany obiektu historii (powiedzmy, kiedy użytkownik pomyślnie się uwierzytelni).W dokumentach React Router spójrz na
<Router>
komponent, a zobaczysz, że masz możliwość przekazania własnego obiektu historii przez rekwizyt. To jest istota rozwiązania - możemy dostarczyć przedmiot Historia sięReact-Router
z punktu A globalny modułu.Kroki:
yarn add history
lubnpm install history --save
utwórz plik o nazwie
history.js
wApp.js
folderze poziomu (taka była moja preferencja)Dodaj ten obiekt historii do komponentu routera w ten sposób
Dostosuj URL podobnie jak przed importując swoją globalną historię obiektu:
Wszystko powinno być teraz zsynchronizowane, a ty masz również dostęp do sposobu ustawiania obiektu historii programowo, a nie poprzez komponent / kontener.
źródło
Route
komponent.TL; DR:
Prosta i deklaratywna odpowiedź jest taka, że musisz jej używać
<Redirect to={URL} push={boolean} />
w połączeniu zsetState()
Pełny przykład tutaj . Przeczytaj więcej tutaj .
PS. W przykładzie użyto inicjalizatorów właściwości ES7 + do inicjalizacji stanu. Zajrzyj tutaj , jeśli jesteś zainteresowany.
źródło
history.push()
metod.Użyj
useHistory
haka, jeśli używasz składników funkcjiMożesz użyć
useHistory
hook, aby uzyskaćhistory
instancję.useHistory
Hak daje dostęp do instancji historii, które można wykorzystać do nawigacji.Użyj
history
właściwości w składnikach stronyReact Router wstrzykuje niektóre właściwości, w tym
history
składniki strony.Zawiń elementy potomne
withRouter
aby wprowadzić właściwości routerawithRouter
otoki wstrzykuje właściwości routera do komponentów. Na przykład możesz użyć tego opakowania, aby wstrzyknąć router do wylogowania komponentu przycisku umieszczonego w menu użytkownika.źródło
Możesz także po prostu użyć rekwizytów, aby uzyskać dostęp do obiektu historii:
this.props.history.push('new_url')
źródło
this.props.history
w swoim komponencie, możesz,import {withRouter} from 'react-router-dom'
a następnieexport default withRouter(MyComponent)
(lubconst MyComponent = withRouter(...)
), a on wstawihistory
element do rekwizytów twojego komponentu.Krok 1: na wierzch można zaimportować tylko jedną rzecz:
Krok 2: Przełóż historię na swojej trasie:
Krok 3: Historia zostanie zaakceptowana jako część rekwizytów w następnym Komponencie, więc możesz po prostu:
To było łatwe i naprawdę potężne.
źródło
To działa:
źródło
Moja odpowiedź jest podobna do Alexa . Nie jestem pewien, dlaczego React-Router uczynił to tak niepotrzebnie skomplikowanym. Dlaczego powinienem owijać mój komponent HoC, aby uzyskać dostęp do tego, co zasadniczo jest globalne?
W każdym razie, jeśli spojrzysz na ich implementację
<BrowserRouter>
, to tylko małe opakowanie historii .Możemy wyciągnąć nieco tę historię, abyśmy mogli ją zaimportować z dowolnego miejsca. Jednak sztuczka polega na tym, że jeśli renderujesz po stronie serwera i próbujesz przejść
import
do modułu historii, nie zadziała, ponieważ używa interfejsów API tylko przeglądarki. Ale to w porządku, ponieważ zwykle przekierowujemy tylko w odpowiedzi na kliknięcie lub inne zdarzenie po stronie klienta. Dlatego prawdopodobnie jest to poprawne:Za pomocą pakietu internetowego możemy zdefiniować niektóre zmienne, abyśmy wiedzieli, w jakim środowisku się znajdujemy:
A teraz możesz
Skądkolwiek. Zwróci tylko pusty moduł na serwerze.
Jeśli nie chcesz używać tych magicznych zmiennych, musisz po prostu znaleźć się
require
w globalnym obiekcie tam, gdzie jest to potrzebne (wewnątrz modułu obsługi zdarzeń).import
nie będzie działać, ponieważ działa tylko na najwyższym poziomie.źródło
Myślę, że @rgommezz obejmuje większość przypadków minus jeden, który moim zdaniem jest dość ważny.
To pozwala mi napisać prostą usługę z działaniami / wywołaniami, które mogę wywołać, aby wykonać nawigację z dowolnego komponentu, który chcę, bez robienia HoC na moich komponentach ...
Nie jest jasne, dlaczego nikt wcześniej nie dostarczył tego rozwiązania. Mam nadzieję, że to pomoże, a jeśli zauważysz jakiś problem, daj mi znać.
źródło
Testuję v4 od kilku dni i .. Jak dotąd kocham to! Po chwili ma to sens.
Miałem również to samo pytanie i uznałem, że radzenie sobie z nim tak, jak poniżej, działa najlepiej (a może nawet tak, jak jest zamierzone). Wykorzystuje stan, operator trójskładnikowy i
<Redirect>
.W konstruktorze ()
W render ()
W module obsługi kliknięć ()
Mam nadzieję, że to pomoże. Daj mi znać.
źródło
Zmagałem się z tym przez jakiś czas - coś tak prostego, ale tak skomplikowanego, ponieważ ReactJS to po prostu zupełnie inny sposób pisania aplikacji internetowych, jest bardzo obcy dla starszych ludzi!
Stworzyłem osobny komponent, aby odciąć bałagan:
Następnie dodaj go do swojej
render()
metody:źródło
Ponieważ nie ma innego sposobu radzenia sobie z tym okropnym projektem, napisałem ogólny komponent, który wykorzystuje podejście
withRouter
HOC . W poniższym przykładzie jest zawijaniebutton
elementu, ale możesz zmienić dowolny potrzebny element, który można kliknąć:Stosowanie:
źródło
Jeśli nie znalazłeś pliku this.props.history w swoim komponencie, spróbuj tego
źródło
Ponieważ czasami wolę przełączać trasy według aplikacji niż przycisków, jest to minimalny działający przykład, który działa dla mnie:
źródło
Dla tych z Was, którzy wymagają przekierowania przed pełnym zainicjowaniem routera za pomocą
React Router
lubReact Router Dom
Możesz zapewnić przekierowanie, po prostu uzyskując dostęp do obiektu historii i wpychając na niego nowy stan w swojej konstrukcjiapp.js
. Rozważ następujące:W tym miejscu chcemy zmienić trasy wyjściowe zależne od poddomeny, wchodząc w interakcję z obiektem historii przed renderowaniem komponentu, możemy skutecznie przekierować, pozostawiając nasze trasy taktowne.
źródło