Con react-router
puedo usar el elemento Link
para crear enlaces que son manejados nativamente por react router.
Veo que internamente llama a this.context.transitionTo(...)
.
Quiero hacer una navegación, pero no desde un enlace, sino desde una selección desplegable por ejemplo. ¿Cómo puedo hacer esto en código? ¿Qué es this.context
?
He visto el mixin Navigation
, pero ¿puedo hacer esto sin mixins?
React-Router 5.1.0+ Respuesta (usando hooks y React >16.8)
Puedes utilizar el nuevo hook useHistory
en los componentes funcionales y en la navegación programada:
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
// use history.push('/some/path') here
};
React-Router 4.0.0+ Respuesta
En la versión 4.0 y superior, utilice el historial como prop de su componente.
class Example extends React.Component {
// use `this.props.history.push('/some/path')` here
};
NOTA: this.props.history no existe en el caso de que su componente no haya sido renderizado por <Ruta>
. Debe utilizar <Ruta path="..." component={SuComponente}/>
para tener this.props.history en SuComponente
React-Router 3.0.0+ Respuesta
En la versión 3.0 y superior, utilice el enrutador como una prop de su componente.
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
React-Router 2.4.0+ Respuesta
En la versión 2.4 y superior, utilice un componente de orden superior para obtener el enrutador como prop de su componente.
import { withRouter } from 'react-router';
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
// Export the decorated class
var DecoratedExample = withRouter(Example);
// PropTypes
Example.propTypes = {
router: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
}).isRequired
};
React-Router 2.0.0+ Respuesta
Esta versión es compatible con la 1.x por lo que no es necesaria una guía de actualización. Basta con repasar los ejemplos para que sea suficiente.
Dicho esto, si desea cambiar al nuevo patrón, hay un módulo browserHistory dentro del router al que puede acceder con
import { browserHistory } from 'react-router'
Ahora tienes acceso al historial de tu navegador, así que puedes hacer cosas como empujar, reemplazar, etc... Como:
browserHistory.push('/alguna/ruta')
Más información: Historias y Navegación
React-Router 1.x.x Respuesta
No voy a entrar en detalles de la actualización. Puede leerlo en la Guía de actualización
El principal cambio sobre la pregunta aquí es el cambio del mixin de Navegación a Historia. Ahora se utiliza el historyAPI del navegador para cambiar de ruta por lo que utilizaremos pushState()
a partir de ahora.
Aquí hay un ejemplo usando Mixin:
var Example = React.createClass({
mixins: [ History ],
navigateToHelpPage () {
this.history.pushState(null, `/help`);
}
})
Ten en cuenta que este History
viene del proyecto rackt/history. No del propio React-Router.
Si no quieres usar Mixin por alguna razón (quizás por la clase ES6), entonces puedes acceder al historial que obtienes del router desde this.props.history
. Sólo será accesible para los componentes renderizados por tu Router. Por lo tanto, si quieres usarlo en cualquier componente hijo, es necesario pasarlo como un atributo a través de props
.
Puedes leer más sobre la nueva versión en su documentación 1.0.x
Aquí hay una página de ayuda específica sobre la navegación fuera de su componente
Recomienda coger una referencia history = createHistory()
y llamar a replaceState
sobre ella.
React-Router 0.13.x Respuesta
Me encontré con el mismo problema y sólo pude encontrar la solución con el mixin Navigation que viene con react-router.
Así es como lo hice
import React from 'react';
import {Navigation} from 'react-router';
let Authentication = React.createClass({
mixins: [Navigation],
handleClick(e) {
e.preventDefault();
this.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
Pude llamar a transitionTo()
sin necesidad de acceder a .context
.
O puedes probar la elegante clase
de ES6
import React from 'react';
export default class Authentication extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
}
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
}
Authentication.contextTypes = {
router: React.PropTypes.func.isRequired
};
React-Router-Redux
Nota: si estás usando Redux, hay otro proyecto llamado React-Router-Redux que te da enlaces Redux para ReactRouter, utilizando un poco el mismo enfoque que React-Redux](https://github.com/rackt/react-redux).
React-Router-Redux tiene algunos métodos disponibles que permiten una navegación sencilla desde dentro de los creadores de acciones. Esto puede ser particularmente útil para las personas que tienen una arquitectura existente en React Native, y desean utilizar los mismos patrones en React Web con un mínimo de sobrecarga.
Explora los siguientes métodos:
push(location)
replace(location)
ir(número)
regresar()
goForward()
Aquí hay un ejemplo de uso, con Redux-Thunk:
./actioncreators.js
import { goBack } from 'react-router-redux'
export const onBackPress = () => (dispatch) => dispatch(goBack())
./viewcomponent.js
<button
disabled={submitting}
className="cancel_button"
onClick={(e) => {
e.preventDefault()
this.props.onBackPress()
}}
>
CANCEL
</button>
React-Router v2
Para la versión más reciente (v2.0.0-rc5
), el método de navegación recomendado es empujar directamente sobre el singleton del historial. Puedes verlo en acción en el documento Navegando fuera de los componentes.
Extracto relevante:
import { browserHistory } from 'react-router';
browserHistory.push('/some/path');
Si se utiliza la nueva API de react-router, es necesario hacer uso de la historia
de this.props
cuando dentro de los componentes así:
this.props.history.push('/some/path');
También ofrece pushState
pero eso está obsoleto por las advertencias registradas.
Si se utiliza react-router-redux
, ofrece una función push
que se puede enviar así:
import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));
Sin embargo, esto sólo se puede utilizar para cambiar la URL, no para navegar realmente a la página.
Atención: esta respuesta sólo cubre las versiones de ReactRouter anteriores a la 1.0
¡Actualizaré esta respuesta con los casos de uso de 1.0.0-rc1 después!
Usted puede hacer esto sin mixins también.
let Authentication = React.createClass({
contextTypes: {
router: React.PropTypes.func
},
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
El problema con los contextos es que no son accesibles a menos que se defina el contextTypes
en la clase.
En cuanto a lo que es el contexto, es un objeto, como los props, que se pasa de padres a hijos, pero se pasa implícitamente, sin tener que volver a declarar los props cada vez. Véase https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html