Jeśli celujesz w środowiska przeglądarki, musisz użyć react-router-dom
pakietu zamiast react-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żywa history
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 React context
, pod warunkiem, że masz komponent <BrowserRouter>
dostawcy jako najwyższy nadrzędny w twojej aplikacji. Biblioteka udostępnia poprzez kontekst router
obiekt, który sam zawiera history
jako właściwość. history
Interfejs oferuje kilka metod nawigacji, takie jakpush
, replace
i goBack
, 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 URL
Dzieje się tak, ponieważ react-router
przechodzi location
do komponentów przy użyciu modelu kontekstowego.
Zarówno connect, jak i obserwator tworzą komponenty, których metody shouldComponentUpdate wykonują płytkie porównanie swoich bieżących rekwizytów i następnych rekwizytów. Te komponenty zostaną zrenderowane tylko, gdy zmieni się co najmniej jeden rekwizyt. Oznacza to, że w celu zapewnienia ich aktualizacji, gdy zmienia się lokalizacja, będą musieli otrzymać rekwizyt, który zmienia się, gdy zmienia się lokalizacja.
Dwa podejścia do rozwiązania tego:
- Zawiń podłączony komponent w ścieżkę bez ścieżki
<Route />
. Obecnylocation
obiekt jest jednym z rekwizytów <Route>
przekazywanych do renderowanego komponentu
- Owiń podłączony komponent komponentem
withRouter
wyższego rzędu, który w rzeczywistości ma ten sam efekt i wstrzykujelocation
jak rekwizyt
Poza tym istnieją cztery sposoby programowej nawigacji, uporządkowane według zaleceń:
1.- Korzystanie z <Route>
komponentu
Promuje deklaratywny styl. Przed wersją v4
<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
wstrzykuje
match
,
location
a
history
jako rekwizyty do swojego komponentu. Metody nawigacji (takie jak
push
,
replace
,
goBack
...) są dostępne jako właściwości
history
obiektu.
Istnieją 3 sposoby renderowania czegoś Route
za pomocą albo component
, render
albo children
rekwizytów, ale nie używaj więcej niż jednego w tym samym Route
. Wybór zależy od przypadku użycia, ale w zasadzie dwie pierwsze opcje renderują komponent tylko wtedy, gdy path
pasuje do lokalizacji children
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ócz match
, location
i history
. Przykład ilustrujący:
import { BrowserRouter as Router } from 'react-router-dom'
const ButtonToNavigate = ({ title, history }) => (
<button
type="button"
onClick={() => history.push('/my-new-location')}
>
{title}
</button>
);
const SomeComponent = () => (
<Route path="/" render={(props) => <ButtonToNavigate {...props} title="Navigate elsewhere" />} />
)
const App = () => (
<Router>
<SomeComponent /> // Notice how in v4 we can have any other component interleaved
<AnotherComponent />
</Router>
);
2.- Korzystanie z withRouter
HoC
Ten 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.
import { withRouter } from 'react-router-dom'
const ButtonToNavigate = ({ history }) => (
<button
type="button"
onClick={() => history.push('/my-new-location')}
>
Navigate
</button>
);
ButtonToNavigate.propTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired,
}),
};
export default withRouter(ButtonToNavigate);
3.- Używanie Redirect
komponentu
Renderowanie a
<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 przez
to
prop, który może być ciągiem (URL do przekierowania) lub
location
obiektem. Jeśli zamiast tego chcesz
wprowadzić nowy wpis do historii ,
push
podaj również rekwizyt i ustaw go na
true
<Redirect to="/your-new-location" push />
4.- Dostęp router
ręczny przez kontekst
Nieco zniechęcony, ponieważ
kontekst jest wciąż eksperymentalnym interfejsem API i może ulec zmianie / zmianie w przyszłych wydaniach React
const ButtonToNavigate = (props, context) => (
<button
type="button"
onClick={() => context.router.history.push('/my-new-location')}
>
Navigate to a new location
</button>
);
ButtonToNavigate.contextTypes = {
router: React.PropTypes.shape({
history: React.PropTypes.object.isRequired,
}),
};
Nie 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średnictwem react-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.