web-dev-qa-db-fra.com

Passer de réagir routeur 3.x à 4.x

Comment puis-je passer à utiliser https://cdnjs.cloudflare.com/ajax/libs/react-router/4.0.0-2/react-router.min.js à partir de https://cdnjs.cloudflare.com/ajax/libs/react-router/3.0.1/ReactRouter.min.js?

Exemple utilisant 3.x ci-dessous.

HTML

<script src="https://unpkg.com/[email protected]/dist/react.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/3.0.1/ReactRouter.min.js"></script>

JS

let { Router, IndexRoute, Redirect, Route, Link, browserHistory } = ReactRouter;

history.replaceState(0,0,'/');

const Main = () =>
  <Router history={browserHistory}>

    <Route path='/' component={App}>
      <IndexRoute component={Home}/>
      <Route path='map' component={Map}/>
      <Route path='settings' component={Settings}/>
            <Redirect from='foo' to='/' />
      <Route path='*' component={NotFound}/>
    </Route>

  </Router>

const App = props => 
  <div>
    <Navigation>
      <Link to='/map'>Map</Link>
      <Link to='/settings'>Settings</Link>
      <Link to='/foo'>Foo</Link>
    </Navigation>

    {props.children}

  </div>

const Navigation = props => <nav {...props} />
const Home = () => <h1>Home</h1>
const Map = () => <h1>Map</h1>
const Settings = () => <h1>Settings</h1>
const NotFound = (props) => <h1>404 - Not Found</h1>

ReactDOM.render(<Main />, document.body);

Voyez-le en action à: https://jsfiddle.net/developit/nvpr63eg/

Si je passe à l’une des versions 4.x hébergées sur CDN, cela ne fonctionne pas (code inaccessible après instruction de retour).

16
rich

J'ai été capable de le configurer avec Redux en changeant quelques petites choses:

Tout d’abord, browserHistory n’est plus défini sur react-router. Une façon de le récupérer consiste à utiliser le package history.

Vous devrez installer (redux en option):

npm i -S history react-router react-router-redux

Au lieu d'essayer d'importer browserHistory, utilisez:

import { createBrowserHistory } from 'history';

Si vous voulez utiliser redux, importez-le et ajoutez-le à vos réducteurs combinés:

import { routerReducer as routing } from 'react-router-redux';

combineReducers({
  home, about,
  routing, // new
});

Ensuite, vous créez l'objet history

// redux
import { syncHistoryWithStore } from 'react-router-redux';
const history = syncHistoryWithStore(createBrowserHistory(), store);

// regular
const history = createBrowserHistory();

Puis changez votre routeur pour utiliser le nouvel objet history

<Router history={ history } children={ Routes } />

Tout le reste devrait être pareil.


Si quelqu'un rencontre The prop history is marked as required in Router, but its value is undefined.

C’est parce que browserHistory n’est plus disponible dans react-router, voir poste à la place.


En relation

13
BrunoLM

Ceci est une réponse complémentaire à celle de Paul S affichée ci-dessus. Le crédit devrait quand même être reçu par Paul pour l'avoir posté.

La raison pour laquelle je complète la réponse est bcoz: - 

  1. J'ai eu des erreurs avec BrowserHistory et Link.
  2. Je devais inclure react-router-dom.
  3. était une faute de frappe (réponse originale de Paul)

étapes de fil:

yarn add react-router
yarn add react-router-dom

package.json:

 "react": "^15.6.1",
    "react-dom": "^15.6.1",
    "react-router": "^4.1.1",
    "react-router-dom": "^4.1.1"

index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import { Switch, Redirect, Route} from 'react-router';
import {BrowserRouter, Link} from 'react-router-dom';


//let { BrowserRouter, Switch, Redirect, Route, Link } = ReactRouter;

const Main = () =>
  <BrowserRouter>
    <App>
      <Switch>
        <Route exact path='/' component={Home}/>
        <Route path='/map' component={Map}/>
        <Route path='/settings' component={Settings}/>
        <Route path='/foo' component={Foo}/>
        <Route component={NotFound}/>
      </Switch>
    </App>
  </BrowserRouter>

const App = props =>
  <div>
    <Navigation>
      <Link to='/map'>Map</Link>
      <Link to='/settings'>Settings</Link>
      <Link to='/foo'>Foo</Link>
    </Navigation>

    {props.children}

  </div>

const Navigation = props => <nav {...props} />
const Home = () => <h1>Home</h1>
const Map = () => <h1>Map</h1>
const Settings = () => <h1>Settings</h1>
const Foo = () => <Redirect to='/' />
const NotFound = (props) => <h1>404 - Not Found</h1>

ReactDOM.render(<Main />, document.body);

 enter image description here

7
Plankton

Il devrait y avoir un guide de mise à niveau plus proche de la version complète. J'ai adapté votre code pour la prochaine version bêta au lieu de l'alpha actuel. La version bêta n'a pas encore été publiée. Malheureusement, vous ne pourrez pas tester cette version hébergée de React Router.

let { BrowserRouter, Switch, Redirect, Route, Link } = ReactRouter;

const Main = () =>
  <BrowserRouter>
    <App>
      <Switch>
        <Route exact path='/' component={Home}/>
        <Route path='/map' component={Map}/>
        <Route path='/settings' component={Settings}/>
        <Route path='/foo' component={Foo}/>
        <Route component={NotFound}/>
      </Switch>
    </App>
  </BrowserRouter>

const App = props => 
  <div>
    <Navigation>
      <Link to='/map'>Map</Link>
      <Link to='/settings'>Settings</Link>
      <Link to='/foo'>Foo</Link>
    </Navigation>

    {props.children}

  </div>

const Navigation = props => <nav {...props} />
const Home = () => <h1>Home</h1>
const Map = () => <h1>Map</h1>
const Settings = () => <h1>Settings</h1>
const Foo = () => <Redirect to='/' />
const NotFound = (props) => <h1>404 - Not Found</h1>

ReactDOM.render(<Main />, document.body);
5
Paul S

Vous le pouvez certainement, mais vous devrez réécrire certains de vos composants et votre logique d’application car votre code ne fonctionnera pas tel qu’il est actuellement.

Ayez une lecture sur la documentation officielle, ici . Il y a aussi une bonne FAQ à propos de ces changements, ici . Voici un extrait:

Pourquoi cet énorme changement?

tl; dr Composabilité déclarative.

Nous n'avons jamais été aussi enthousiasmés par React Router. Comme vous, nous avons beaucoup appris sur React depuis que nous l'avons découvert. Nous avons construit le meilleur routeur possible. Ce que nous avons appris le plus, c’est que nous aimons React à cause de sa possibilité de composition déclarative.

Si vous souhaitez effectuer une mise à niveau, un guide de mise à niveau est bientôt disponible, selon une source officielle:

Nous croyons fermement en une migration itérative, et non en une réécriture, pour les applications. Nous travaillons sur un guide de migration, mais la stratégie de base est que les deux versions seront exécutables en tandem (en raison des limitations de npm, nous publierons la version précédente séparément pour pouvoir les installer toutes les deux).

Vous pourrez prendre les itinéraires un par un et les migrer vers la nouvelle API. De plus, l'addon de configuration mentionné ci-dessus peut aider ici.


Dans cet esprit, revenons à votre question initiale: pour que votre composant App fonctionne correctement, il devrait maintenant ressembler à ceci:

const App = props => 
  <div>
    <Navigation>
      <Link to='/map'>Map</Link>
      <Link to='/settings'>Settings</Link>
      <Link to='/foo'>Foo</Link>
    </Navigation>
    {props.children}
  </div>

  <Match exactly pattern="/" component={Home} />
  <Match pattern="/map" component={Map} />
  <Match pattern="/settings" component={Settings} />
  <Match pattern="/topics" component={Topics} />

J'espère que cela t'aides. Bonne chance.


edit: Apparemment, @PaulS a un exemple pour une future version de React-Router v4. Si le message est exact, le code ci-dessus ne fonctionnera pas à l'avenir; cela ne fonctionnera que pour la version actuelle disponible. Gardez un œil sur les pages liées ci-dessus pour plus d'informations lorsque RRv4 sera mis en ligne.

0
Chris

Il y a quelques choses à noter avec la récente version de v4, concernant votre jsfiddle. La première chose est que la bibliothèque dans son ensemble a été séparée: Web, native et principale (à utiliser n'importe où). Utilisez react-router-dom pour le Web uniquement. 

2: La façon dont vous nichez les routes est assez différente. Au lieu d'imbriquer des itinéraires dans votre composant parent, ce que vous ne pouvez pas réellement faire, il vous suffit de définir votre composant parent (BrowserRouter dans ce cas), puis vous êtes libre de définir des itinéraires dans vos composants. Vos composants définissent la hiérarchie maintenant. Par exemple, vous pouvez organiser vos composants principaux et d'applications de la manière suivante:

const Main = () => (
  <BrowserRouter>
    <App />
  </BrowserRouter>
)

const App = props => (
  <div>
    <Navigation>
      <Link to='/'>Home</Link>
      <Link to='/map'>Map</Link>
      <Link to='/settings'>Settings</Link>
      <Link to='/foo'>Foo</Link>
    </Navigation>

    <Route exact path='/' component={Home}/>
    <Route path='/map' component={Map}/>
    <Route path='/settings' component={Settings}/>
    <Route path='/foo' render={() => (
        <Redirect to="/"/>
    )}/>
  </div>
)

J'espère que cela t'aides. S'il vous plaît jeter un oeil à mon correctif pour votre jsfiddle ci-dessous, et laissez-moi savoir si vous avez des questions.

https://jsfiddle.net/bagofcole/kL6m8pjk/12/

Pour plus d'informations, consultez: https://reacttraining.com/react-router/web/guides/quick-start

0
bagofcole