Cómo actualizar a React Router 4

No mucho después de que comencé a trabajar en mi puesto actual, el equipo se dio cuenta de que sería necesario actualizarnos a React 16 para poder usar una nueva biblioteca de IU que estábamos interesados ​​en adoptar.

Para averiguar cuánto tiempo requeriría esta actualización, revisamos todos nuestros paquetes actuales para ver si eran compatibles con React 16 y para ver si todavía estábamos usando paquetes obsoletos o no admitidos.

Los inicios de nuestra base de código habían sido creados por desarrolladores que usaban cualquier biblioteca de código abierto o de terceros que quisieran, sin examinarlos realmente. Por lo tanto, descubrimos que muchos de los paquetes estaban obsoletos y debían reemplazarse lo antes posible.

Una de las mayores sorpresas para nosotros fue la desaprobación de react-router-redux. Estábamos usando react-router-reduxjunto con react-router v3. Esto nos llevó a pensar críticamente acerca de por qué estábamos usando reduxnuestro enrutador en primer lugar.

Una vez que comenzamos a buscar en el enrutador react v4, nos dimos cuenta de que las nuevas funciones eliminarían prácticamente cualquier motivo para que usemos una biblioteca adicional para conectar nuestro enrutador y redux. Entonces, eso nos dejó en la posición de actualizar del enrutador react 3 al 4 y eliminarlo   react-router-reduxde nuestra aplicación.

Entonces, tuve la tarea de actualizar nuestro enrutador a v4 después de estar en el puesto y trabajar con React durante aproximadamente 2 meses. Esto se debía a que la actualización de React Router 3 a React Router 4 parecía una tarea trivial. Pero, como descubrí rápidamente, fue un poco más complicado de lo que esperaba.

Al revisar la documentación, el repositorio de GitHub y muchas, muchas respuestas de Stack Overflow, finalmente reuní los pasos para la actualización y quise compartir mis hallazgos, especialmente para explicar cómo y por qué se realizan ciertos cambios.

El mayor cambio a tener en cuenta, de los creadores de React Router, es que la actualización de React Router 3 a React Router 4 es más que solo actualizar algunas bibliotecas y características: le permite cambiar fundamentalmente cómo funciona su enrutador. Los creadores de React Router querían volver a un enrutador simple, permitiendo al desarrollador personalizarlo como quisieran.

He dividido esta guía en 5 partes diferentes:

  1. Paquete
  2. Historia
  3. Ruta
  4. Accesorios
  5. Integración Redux

Paquete

La estructura del paquete React Router v4 cambió de tal manera que ya no es necesario instalar react-router; tiene que instalar react-router-dom(y desinstalar react-router), pero no pierde nada ya que reexporta todas react-routerlas exportaciones. Esto significa que también debe actualizar las   react-routerdeclaraciones de importación a react-router-dom.

Historia

La historia es una parte esencial del enrutamiento, lo que nos permite recordar de dónde venimos y dónde nos encontramos actualmente. La historia se presenta de muchas formas para react-router, y podría llevar un tiempo explicarla. Entonces, para mantener este artículo sobre el tema, simplemente le recomendaré que lea este artículo que explica el historial en relación con el enrutador react 4. Este artículo debería cubrir la mayoría de los casos de su uso del historial.

Ruta

React Router v3 nos permitió colocar todas las rutas de nuestra aplicación en un archivo, al que llamaremos router.js. Sin embargo, React Router v4 le permite colocar rutas en los componentes que están renderizando. La idea aquí es enrutar dinámicamente la aplicación; en otras palabras, el enrutamiento tiene lugar mientras la aplicación se está procesando.

Sin embargo, si tiene una base de código heredada de tamaño decente con la que está trabajando, probablemente no hará un cambio tan grande. Afortunadamente, React Router v4 aún te permite colocar todas las rutas en un archivo central, que es como crearé todos nuestros ejemplos. Sin embargo, hay algunos componentes y funciones más antiguos que deberán reemplazarse.

IndexRoute

Anteriormente,   IndexRoutese usaba como ruta para alguna interfaz de usuario predeterminada de una ruta principal. Pero, en v4, IndexRouteya no se usa, ya que esta funcionalidad ahora está disponible en Route.

Para proporcionar una interfaz de usuario predeterminada, varias rutas que tienen la misma ruta permitirán que todos los componentes asociados se representen:

import { BrowserRouter as Router, Route } from 'react-router-dom';  // example of our route components    

Por lo tanto, todos los componentes - Home, Abouty Contact- rendirá. Debido a esto, tampoco puede anidar rutas.

Además, para permitir una mejor coincidencia sin el uso de IndexRoute, puede usar la palabra clave exacta.

import { BrowserRouter as Router, Route } from 'react-router-dom';  // example of our route components   

Enrutamiento exclusivo

Después de agregar la palabra clave exacta, “something.com/about”se enrutará cuando el enrutador vea una ruta “/about”. Pero ahora, ¿y si tienes otro camino “/about/team”? Como dije antes, el enrutador renderizará cualquier cosa que coincida. Entonces, los componentes asociados con ambos “/about”y   “/about/team”se renderizarán. Si eso es lo que pretendías, ¡genial! Sin embargo, si esto no es lo que desea, es posible que deba colocar un interruptor alrededor de este grupo de rutas. Esto permitirá que se procese la primera ruta que coincida con la URL.

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';       

Tenga en cuenta que la palabra clave exacta todavía tiene que aparecer para el componente Inicio; de lo contrario, coincidiría con las rutas posteriores. También tenga en cuenta que tenemos que listar “/about/team”antes “/about”para que la ruta vaya al Teamcomponente en lugar del Aboutcomponente cuando lo vea   “something.com/about/team”. Si viera “/about”primero, se detendría allí y renderizaría el Aboutcomponente porque Switch solo renderiza el primer componente que coincide.

Ruta por defecto

Una ruta predeterminada, o una ruta "atrapar todo", comúnmente utilizada para páginas 404, es la ruta que usa cuando ninguna de las rutas coincide.

En React Router v3, el valor predeterminado Routeera:

En React Router v4, el valor predeterminado Routese cambió a:

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';       // this is our default route  

When  you don’t include a path in a Route, the component will always render.  So, as we discussed above, we can use Switch to get only one component  to render, and then place the “catch all” route very last (so it doesn’t  use that one before the Router gets a chance to check the rest of the  paths), so something will always render even if the other paths don’t  match.

onEnter

Previously,  you could use onEnter to make sure the component of the Route has all  of the information it needs or as a check (such as to make sure the user  is authenticated) before the component rendered.

This  feature has been deprecated because the new structure of Routes is that  they should act like components, so you should take advantage of component lifecycle methods instead.

In React Router v3:

Becomes:

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';        
... componentDidMount() { this.props.fetchInfo(); } ...

Props

In  React Router v4, the props passed through the router have changed, as  did the way they are accessed. The Route now passes three props:

  • history
  • location
  • match

history

history contains a lot of other properties and methods, so I won’t list all of  them, but here is a selection that might be most commonly used:

  • length: number of entries in the history stack
  • location: contains the same information as below
  • push(path, [state]): pushes new entry on history stack
  • goBack(): allows you to move the pointer on the history stack back 1 entry

It’s  important to note that history is mutable, and while it contains a location property, this instance of location shouldn’t be used since it  could have been changed. Instead, you want to use the actual location prop discussed below.

location

The location has properties:

  • pathname
  • search
  • hash
  • state

location.search is used to replace location.query and it must be parsed. I used  URLSearchParams to parse it. So a URL such as  “//something.com/about?string=’hello’” would be parsed as such:

... const query = new URLSearchParams(this.props.location.search) const string = query.get('string') // string = 'hello' ...

Additionally,  the state property can be used to pass the location-specific state of components through props. So, if you wanted to pass some information  from one component to another, you could use it like this:

... // To link to another component, we could do this:  // However, if we wanted to add state to the location, we could do this: const location = { pathname: '/path/', state: { fromDashboard: true }, }  ...

So, once we get to the component rendered by that path, we’ll have access to fromDashboard from location.state.fromDashboard.

match

match has the following properties:

  • params:  gets the dynamic segments of the path from the URL — for example if the  path is “/about/:id”, in the component, accessing  this.props.match.params will give you the id in the URL
  • isExact: true if the entire URL was matched
  • path: the path in the routes that was matched
  • url: the matched portion of the URL

Redux Integration

As  I addressed earlier, we found that in our case, we didn’t need to have an additional library to connect redux with our router, especially since our main use case for this — Blocked Updates — was covered by react  router.

Blocked Updates

In  some cases, the app doesn’t update when the location changes. This is called a “Blocked Update”. This can happen if both of these conditions  are met:

  1. The component is connected to Redux via connect()(Component).
  2. The component isn’t rendered by a

In these cases, I wrapped the component’s connect with withRouter.

This  allowed the router information to follow the component when it gets linked to, so the app still updates when the Redux state changes.

And that’s it!

This upgrade took me over a week — a few days of trying to figure out how to do it at all, and then another few days to start actually making changes. Upgrading to React Router 4 is a huge change not to be taken lightly, but it’ll make your router a lot more lightweight and easy to use.

Please don’t hesitate to comment/ask questions!