¿Cómo pasar al historial en React Router v4?

Resuelto Chris asked hace 7 años • 24 respuestas

En la versión actual de React Router (v3), puedo aceptar una respuesta del servidor y usarla browserHistory.pushpara ir a la página de respuesta adecuada. Sin embargo, esto no está disponible en la versión 4 y no estoy seguro de cuál es la forma adecuada de manejarlo.

En este ejemplo, usando Redux, componentes/app-product-form.js llama this.props.addProduct(props)cuando un usuario envía el formulario. Cuando el servidor devuelve un éxito, el usuario es llevado a la página del carrito.

// actions/index.js
export function addProduct(props) {
  return dispatch =>
    axios.post(`${ROOT_URL}/cart`, props, config)
      .then(response => {
        dispatch({ type: types.AUTH_USER });
        localStorage.setItem('token', response.data.token);
        browserHistory.push('/cart'); // no longer in React Router V4
      });
}

¿Cómo puedo realizar una redirección a la página del carrito desde la función React Router v4?

Chris avatar Mar 09 '17 23:03 Chris
Aceptado

Puede utilizar los historymétodos fuera de sus componentes. Pruebe de la siguiente manera.

Primero, cree un historyobjeto que utilice el paquete histórico :

// src/history.js

import { createBrowserHistory } from 'history';

export default createBrowserHistory();

Luego envuélvalo en <Router>( tenga en cuenta que debe usar import { Router }en lugar de import { BrowserRouter as Router }):

// src/index.jsx

// ...
import { Router, Route, Link } from 'react-router-dom';
import history from './history';

ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
      <div>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/login">Login</Link></li>
        </ul>
        <Route exact path="/" component={HomePage} />
        <Route path="/login" component={LoginPage} />
      </div>
    </Router>
  </Provider>,
  document.getElementById('root'),
);

Cambie su ubicación actual desde cualquier lugar, por ejemplo:

// src/actions/userActionCreators.js

// ...
import history from '../history';

export function login(credentials) {
  return function (dispatch) {
    return loginRemotely(credentials)
      .then((response) => {
        // ...
        history.push('/');
      });
  };
}

UPD : También puede ver un ejemplo ligeramente diferente en las preguntas frecuentes de React Router .

Oleg Belostotsky avatar Aug 23 '2017 21:08 Oleg Belostotsky

React Router v4 es fundamentalmente diferente de v3 (y anteriores) y no puedes hacer browserHistory.push()como antes.

Esta discusión parece relacionada si quieres más información:

  • Crear un nuevo browserHistoryno funcionará porque <BrowserRouter>crea su propia instancia de historial y escucha los cambios al respecto. Entonces, una instancia diferente cambiará la URL pero no actualizará el archivo <BrowserRouter>.
  • browserHistoryno está expuesto por react-router en v4, solo en v2.

En su lugar, tienes algunas opciones para hacer esto:

  • Utilice el withRoutercomponente de orden superior

    En su lugar, debe utilizar el withRoutercomponente de orden superior y ajustarlo al componente que pasará al historial. Por ejemplo:

    import React from "react";
    import { withRouter } from "react-router-dom";
    
    class MyComponent extends React.Component {
      ...
      myFunction() {
        this.props.history.push("/some/Path");
      }
      ...
    }
    export default withRouter(MyComponent);
    

    Consulte la documentación oficial para obtener más información:

    Puede obtener acceso a las historypropiedades del objeto y a <Route>las más cercanas matcha través del componente de orden superior withRouter. withRouter volverá a renderizar su componente cada vez que la ruta cambie con los mismos accesorios que <Route>render props: { match, location, history }.


  • Utilice la contextAPI

    Usar el contexto puede ser una de las soluciones más sencillas, pero al ser una API experimental, es inestable y no es compatible. Úselo sólo cuando todo lo demás falle. He aquí un ejemplo:

    import React from "react";
    import PropTypes from "prop-types";
    
    class MyComponent extends React.Component {
      static contextTypes = {
        router: PropTypes.object
      }
      constructor(props, context) {
         super(props, context);
      }
      ...
      myFunction() {
        this.context.router.history.push("/some/Path");
      }
      ...
    }
    

    Eche un vistazo a la documentación oficial sobre contexto:

    Si desea que su aplicación sea estable, no utilice el contexto. Es una API experimental y es probable que falle en futuras versiones de React.

    Si insiste en usar el contexto a pesar de estas advertencias, intente aislar su uso en un área pequeña y evite usar la API de contexto directamente cuando sea posible para que sea más fácil de actualizar cuando la API cambie.

Chris avatar Mar 10 '2017 10:03 Chris

Ahora con reaccionar-router v5 puedes usar el gancho useHistory de esta manera:

import { useHistory } from "react-router-dom";

function HomeButton() {
  let history = useHistory();

  function handleClick() {
    history.push("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}

lea más en: https://reacttraining.com/react-router/web/api/Hooks/usehistory

Hadi Abu avatar Oct 24 '2019 07:10 Hadi Abu

La forma más sencilla en React Router 4 es usar

this.props.history.push('/new/url');

Pero para utilizar este método, su componente existente debe tener acceso al historyobjeto. Podemos acceder mediante

  1. Si su componente está vinculado Routedirectamente, entonces su componente ya tiene acceso al historyobjeto.

    p.ej:

    <Route path="/profile" component={ViewProfile}/>
    

    Aquí ViewProfiletiene acceso a history.

  2. Si no está conectado Routedirectamente.

    p.ej:

    <Route path="/users" render={() => <ViewUsers/>}
    

    Luego tenemos que usar withRouter, una función de orden superior para deformar el componente existente.

    ViewUsersComponente interior

    • import { withRouter } from 'react-router-dom';

    • export default withRouter(ViewUsers);

    Eso es todo ahora, su ViewUserscomponente tiene acceso al historyobjeto.

ACTUALIZAR

2- en este escenario, pase todas las rutas propsa su componente y luego podremos acceder this.props.historydesde el componente incluso sin unHOC

p.ej:

<Route path="/users" render={props => <ViewUsers {...props} />}
Saahithyan Vigneswaran avatar Dec 24 '2018 18:12 Saahithyan Vigneswaran