¿Cómo pasar al historial en React Router v4?
En la versión actual de React Router (v3), puedo aceptar una respuesta del servidor y usarla browserHistory.push
para 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?
Puede utilizar los history
métodos fuera de sus componentes. Pruebe de la siguiente manera.
Primero, cree un history
objeto 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 .
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
browserHistory
no 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>
.browserHistory
no está expuesto por react-router en v4, solo en v2.
En su lugar, tienes algunas opciones para hacer esto:
Utilice el
withRouter
componente de orden superiorEn su lugar, debe utilizar el
withRouter
componente 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
history
propiedades del objeto y a<Route>
las más cercanasmatch
a 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
context
APIUsar 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.
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
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 history
objeto. Podemos acceder mediante
Si su componente está vinculado
Route
directamente, entonces su componente ya tiene acceso alhistory
objeto.p.ej:
<Route path="/profile" component={ViewProfile}/>
Aquí
ViewProfile
tiene acceso ahistory
.Si no está conectado
Route
directamente.p.ej:
<Route path="/users" render={() => <ViewUsers/>}
Luego tenemos que usar
withRouter
, una función de orden superior para deformar el componente existente.ViewUsers
Componente interiorimport { withRouter } from 'react-router-dom';
export default withRouter(ViewUsers);
Eso es todo ahora, su
ViewUsers
componente tiene acceso alhistory
objeto.
ACTUALIZAR
2
- en este escenario, pase todas las rutas props
a su componente y luego podremos acceder this.props.history
desde el componente incluso sin unHOC
p.ej:
<Route path="/users" render={props => <ViewUsers {...props} />}