Se scegli come target gli ambienti browser, devi utilizzare il react-router-dom
pacchetto anziché react-router
. Stanno seguendo lo stesso approccio di React, al fine di separare core, ( react
) e il codice specifico della piattaforma, ( react-dom
, react-native
) con la sottile differenza che non è necessario installare due pacchetti separati, quindi i pacchetti di ambiente contengono tutto hai bisogno. Puoi aggiungerlo al tuo progetto come:
yarn add react-router-dom
o
npm i react-router-dom
La prima cosa che devi fare è fornire a <BrowserRouter>
come componente principale principale nella tua applicazione. <BrowserRouter>
usa l' history
API HTML5 e la gestisce per te, quindi non devi preoccuparti di crearne un'istanza e passarla al <BrowserRouter>
componente come prop (come dovevi fare nelle versioni precedenti).
In V4, per navigare a livello di codice è necessario accedere history
all'oggetto, che è disponibile tramite React context
, purché si disponga di un componente <BrowserRouter>
provider come il principale principale nella propria applicazione. La libreria espone attraverso il contesto l' router
oggetto che esso stesso contiene history
come proprietà. L' history
interfaccia offre diversi metodi di navigazione, come push
, replace
e goBack
, tra gli altri. Puoi controllare l'intero elenco di proprietà e metodi qui .
Nota importante per gli utenti Redux / Mobx
Se si utilizza redux o mobx come libreria di gestione dello stato nella propria applicazione, è possibile che si siano verificati problemi con componenti che dovrebbero essere in grado di riconoscere la posizione ma non essere nuovamente riprodotti dopo aver attivato un aggiornamento URL
Ciò accade perché react-router
passa location
ai componenti utilizzando il modello di contesto.
Sia la connessione che l'osservatore creano componenti i cui metodi shouldComponentUpdate fanno un confronto superficiale tra i loro oggetti di scena attuali e quelli successivi. Quei componenti verranno ri-renderizzati solo quando almeno un puntello è cambiato. Ciò significa che, al fine di garantire che si aggiornino quando la posizione cambia, sarà necessario disporre di un sostegno che cambi quando la posizione cambia.
I 2 approcci per risolvere questo sono:
- Avvolgi il tuo componente collegato in un percorso
<Route />
. L' location
oggetto corrente è uno degli oggetti di scena che a <Route>
passa al componente che rende
- Avvolgi il tuo componente collegato con il
withRouter
componente di ordine superiore, che in effetti ha lo stesso effetto e inietta location
come un oggetto di scena
A parte questo, ci sono quattro modi per navigare programmaticamente, ordinati per raccomandazione:
1.- Utilizzo di un <Route>
componente
Promuove uno stile dichiarativo. Prima della v4, i
<Route />
componenti erano collocati nella parte superiore della gerarchia dei componenti, pensando prima alla struttura dei percorsi. Tuttavia, ora puoi avere
<Route>
componenti
ovunque nell'albero, che ti consentono di avere un controllo più preciso per il rendering condizionale a seconda dell'URL.
Route
inietta
match
,
location
e
history
come oggetti di scena nel tuo componente. I metodi di navigazione (come ad esempio
push
,
replace
,
goBack
...) sono disponibili come proprietà
history
dell'oggetto.
Ci sono 3 modi per rendere qualcosa con una Route
, utilizzando uno component
, render
o di children
oggetti di scena, ma non usare più di uno nello stesso Route
. La scelta dipende dal caso d'uso, ma fondamentalmente le prime due opzioni renderanno il tuo componente solo se path
corrisponde alla posizione dell'URL, mentre conchildren
dell'URL il componente verrà visualizzato se il percorso corrisponde alla posizione o meno (utile per regolare l'interfaccia utente in base all'URL corrispondenza).
Se si desidera personalizzare l'output di rendering del componente , è necessario avvolgere il componente in una funzione e utilizzare l' render
opzione per passare al componente eventuali altri oggetti di scena che desideri, a parte match
, location
e history
. Un esempio per illustrare:
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.- Utilizzo di withRouter
HoC
Questo componente di ordine superiore inietterà gli stessi oggetti di scena di Route
. Tuttavia, comporta la limitazione che è possibile avere solo 1 HoC per file.
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.- Utilizzo di un Redirect
componente
Il rendering a
<Redirect>
consente di spostarsi in una nuova posizione. Tuttavia, tieni presente che,
per impostazione predefinita , la posizione corrente viene sostituita da quella nuova, come i reindirizzamenti lato server (HTTP 3xx). La nuova posizione è fornita da
to
prop, che può essere una stringa (URL a cui reindirizzare) o un
location
oggetto. Se invece vuoi inserire
una nuova voce nella cronologia , passa anche un oggetto di
push
scena e impostalo su
true
<Redirect to="/your-new-location" push />
4.- Accesso router
manuale attraverso il contesto
Un po 'scoraggiato perché il
contesto è ancora un'API sperimentale ed è probabile che si rompa / cambi nelle versioni future di 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,
}),
};
Inutile dire che ci sono anche altri componenti del router che sono pensati per gli ecosistemi non browser, come quello <NativeRouter>
che replica uno stack di navigazione in memoria e targetizza la piattaforma React Native, disponibile attraverso il react-router-native
pacchetto.
Per ogni ulteriore riferimento, non esitate a dare un'occhiata ai documenti ufficiali . C'è anche un video realizzato da uno dei coautori della libreria che fornisce un'introduzione piuttosto interessante al reagente-router v4, evidenziando alcuni dei principali cambiamenti.