Tengo la siguiente estructura para mi aplicación React.js usando React Router :
var Dashboard = require('./Dashboard');
var Comments = require('./Comments');
var Index = React.createClass({
render: function () {
return (
<div>
<header>Some header</header>
<RouteHandler />
</div>
);
}
});
var routes = (
<Route path="/" handler={Index}>
<Route path="comments" handler={Comments}/>
<DefaultRoute handler={Dashboard}/>
</Route>
);
ReactRouter.run(routes, function (Handler) {
React.render(<Handler/>, document.body);
});
Quiero pasar algunas propiedades al Comments componente.
(normalmente haría esto como <Comments myprop="value" /> )
¿Cuál es la forma más fácil y correcta de hacerlo con React Router?
javascript
properties
reactjs
react-router
Kosmetika
fuente
fuente

<ComponentA x={<ComponentB y={<ComponentC z={} />} />} />OR<ComponentA x={ComponentB(ComponentC()) } />De lo contrario, estos problemas de combinaciones de abstracciones se repetirán y necesitarán algunas soluciones menos que óptimas e indirectas llamadas soluciones alternativas como envolver, etc., etc. Las abstracciones deben ser ciudadanos de primera clase como primitivos, cualquiera que sea la percepción de primera clase.Respuestas:
ACTUALIZAR
Desde la nueva versión, es posible pasar accesorios directamente a través del
Routecomponente, sin usar un Wrapper. Por ejemplo, mediante el uso derenderprop .Componente:
Uso:
Ejemplo de código y caja
VERSIÓN ANTIGUA
Mi forma preferida es envolver el
Commentscomponente y pasar el contenedor como un controlador de ruta.Este es su ejemplo con los cambios aplicados:
fuente
<Route path="comments" component={() => (<Comments myProp="value" />)}/>Si prefiere no escribir envoltorios, supongo que podría hacer esto:
fuente
routeobjetos simples en su componente. Aquí está la respuesta del problema de github: github.com/rackt/react-router/issues/615#issuecomment-100432086Copiando de los comentarios de ciantic en la respuesta aceptada:
Esta es la solución más elegante en mi opinión. Funciona. Me ayudó.
fuente
_refcomponent={(props) => (<Comments myProp="value" location={ props.location } />)}pero todo se vuelve desordenado nuevamentecomponent={(props) => (<Comments {...props} myProp="value" />)}mantener los accesorios inyectadosEsta es la solución de Rajesh , sin los inconvenientes comentados por yuji , y actualizada para React Router 4.
El código sería así:
Tenga en cuenta que yo uso
renderlugar decomponent. La razón es para evitar el montaje no deseado . También paso elpropsmétodo y utilizo los mismos accesorios en el componente Comentarios con el operador de propagación de objetos (propuesta ES7).fuente
Solo un seguimiento de la respuesta de ColCh. Es bastante fácil abstraer la envoltura de un componente:
Todavía no he probado esta solución, por lo que cualquier comentario es importante.
Es importante tener en cuenta que con este método, cualquier accesorio enviado a través del enrutador (como los parámetros) se sobrescribe / elimina.
fuente
return React.createElement(Component, _.assign({}, this.props, props));(Este usa _.assign para componer el objeto combinado ... otros métodos están disponibles, por supuesto).render,componentychildrenmétodos paraRoute. Tenga en cuenta que, como señala @dgrcode answer , debe usar enrenderlugar decomponentPuede pasar los accesorios pasándolos a
<RouteHandler>(en v0.13.x) o al componente Route en sí en v1.0;(de la guía de actualización en https://github.com/rackt/react-router/releases/tag/v1.0.0 )
Todos los manipuladores de niños recibirán el mismo conjunto de accesorios; esto puede ser útil o no dependiendo de las circunstancias.
fuente
React.cloneElementse pasan múltiples elementos, pero la firma de la función parece tomar solo un elemento de reacción. Creo que este fragmento se puede hacer más fácil de entender.React.cloneElement(this.props.children, {myprop: "value"})oReact.cloneElement(this.props.children, {myprop: this.props.myprop})etc.Usando ES6 puede simplemente hacer envoltorios de componentes en línea:
<Route path="/" component={() => <App myProp={someValue}/>} >Si necesita pasar niños:
<Route path="/" component={(props) => <App myProp={someValue}>{props.children}</App>} >fuente
renderlugar decomponentReact-router v4 alpha
ahora hay una nueva forma de hacerlo, aunque muy similar al método anterior.
PD: esto funciona solo en la versión alfa, y se eliminaron después de la versión alfa v4. En v4 más reciente, es una vez más, con la ruta y los accesorios exactos.
react-lego, una aplicación de ejemplo contiene código que hace exactamente esto en routes.js en su rama react-router-4
fuente
Aquí está la solución más limpia que se me ocurrió (React Router v4):
MyComponenttodavía tieneprops.matchyprops.location, y tieneprops.foo === "lol".fuente
Envuélvalo con un componente de función sin estado:
fuente
También podría usar la combinación RouteHandler para evitar el componente envoltorio y transmitir más fácilmente el estado de los padres como accesorios:
fuente
Puedes pasar accesorios de
<RouterHandler/>esta manera:La desventaja de esto es que estás pasando accesorios indiscriminadamente. Entonces,
Commentspuede terminar recibiendo accesorios que realmente están destinados a un componente diferente dependiendo de la configuración de sus rutas. No es un gran problema ya quepropses inmutable, pero esto puede ser problemático si dos componentes diferentes esperan un accesorio con un nombrefoopero con valores diferentes.fuente
{...props}En 1.0 y 2.0 puede usar
createElementprop ofRouterpara especificar cómo crear exactamente su elemento de destino. Fuente de documentaciónfuente
También puede combinar es6 y funciones sin estado para obtener un resultado mucho más limpio:
fuente
this.propsuna función, que estoy bastante seguro de que no funcionará. Si está utilizando funciones puras en lugar de extenderlasReact.Component, debe pasarlaspropscomo argumento, consulte los documentos React en Componentes y accesoriosSolución React Router v 4
Hoy me topé con esta pregunta, y aquí está el patrón que uso. Esperemos que esto sea útil para cualquiera que busque una solución más actual.
No estoy seguro de si esta es la mejor solución, pero este es mi patrón actual para esto. Por lo general, tengo un directorio Core donde guardo mis componentes de uso común con sus configuraciones relevantes (cargadores, modales, etc.), e incluyo un archivo como este:
Luego, en el archivo en cuestión, haré lo siguiente:
Notarás que importo la exportación predeterminada de mi componente como humilde camel-case, lo que me permite nombrar el nuevo componente de ubicación en CamelCase para poder usarlo normalmente. Además de la línea de importación adicional y la línea de asignación, el componente se comporta como se esperaba y recibe todos sus accesorios normalmente, con la adición de todos los accesorios de ruta. Por lo tanto, puedo redirigir felizmente desde los métodos de ciclo de vida de los componentes con this.props.history.push (), verificar la ubicación, etc.
¡Espero que esto ayude!
fuente
Para reaccionar router 2.x.
y en tus rutas ...
asegúrese de que la tercera parámetro es un objeto como:
{ checked: false }.fuente
El problema con el React Router es que renderiza sus componentes y, por lo tanto, evita que pase los accesorios. El enrutador de navegación , por otro lado, le permite renderizar sus propios componentes. Eso significa que no tiene que saltar a través de los aros para pasar los accesorios como se muestra en el siguiente código y el JsFiddle que lo acompaña .
fuente
Use el componente con o sin enrutador basado en la respuesta Rajesh Naroth.
O podrías hacerlo de esta manera:
fuente
para el enrutador reactivo 2.5.2, la solución es muy fácil:
fuente
Con un componente de ruta personalizado , esto es posible en React Router v3.
En cuanto al
<MyRoute>código del componente, debería ser algo como:Para obtener más detalles sobre el enfoque del componente de ruta personalizado, consulte mi publicación de blog sobre el tema: http://marmelab.com/blog/2016/09/20/custom-react-router-component.html
fuente
esta es probablemente la mejor manera de usar react-router-dom con un controlador de cookies
en index.js
y use una cookie
fuente
fuente
Use la solución como se muestra a continuación y esto funciona en v3.2.5.
o
fuente