style attribute javascript properties reactjs react-router

javascript - attribute - title css



enrutador de reacción-pasar los apoyos al componente controlador (20)

React-router v4 alfa

Ahora hay una nueva forma de hacerlo, aunque muy similar al método anterior.

import { Match, Link, Miss } from ''react-router''; import Homepage from ''./containers/Homepage''; const route = { exactly: true, pattern: ''/'', title: `${siteTitle} - homepage`, component: Homepage } <Match { ...route } render={(props) => <route.component {...props} />} />

PS Esto funciona solo en la versión alfa y se eliminó después de la versión alfa de v4. En v4 más reciente, es una vez más, con la ruta y los apoyos exactos.

react-lego una aplicación de ejemplo contiene código que hace exactamente esto en route.js en su rama react-router-4

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 en el componente Comments .

(Normalmente haría esto como <Comments myprop="value" /> )

¿Cuál es la forma más fácil y correcta de hacerlo con React Router?


Aquí está la solución más limpia que he encontrado (React Router v4):

<Route path="/" component={props => <MyComponent {...props} foo="lol" />} />

MyComponent aún tiene props.match y props.location , y tiene props.foo === "lol" .


Copia de los comentarios por Ciantic en la respuesta aceptada:

<Route path="comments" component={() => (<Comments myProp="value" />)}/>

Esta es la solución más elegante en mi opinión. Funciona. Me ayudó.


El problema con el enrutador React es que procesa tus componentes y, por lo tanto, evita que pases los apoyos. El enrutador de navegación , por otro lado, le permite renderizar sus propios componentes. Eso significa que no tienes que saltar a través de ningún aro para pasar los apoyos como el siguiente código y el espectáculo de JsFiddle acompaña.

var Comments = ({myProp}) => <div>{myProp}</div>; var stateNavigator = new Navigation.StateNavigator([ {key:''comments'', route:''''} ]); stateNavigator.states.comments.navigated = function(data) { ReactDOM.render( <Comments myProp="value" />, document.getElementById(''content'') ); } stateNavigator.start();


En 1.0 y 2.0 puede usar la propiedad createElement de Router para especificar exactamente cómo crear su elemento de destino. Fuente de documentación

function createWithDefaultProps(Component, props) { return <Component {...props} myprop="value" />; } // and then <Router createElement={createWithDefaultProps}> ... </Router>


Envuélvalo con un componente de función sin estado:

<Router> <Route path=''/'' component={({children}) => <MyComponent myProp={''myVal''}>{children}</MyComponent/> }/> </Router>


Esta es la solución de Rajesh , sin el inconveniente comentado por yuji , y actualizado para React Router 4.

El código sería así:

<Route path="comments" render={(props) => <Comments myProp="value" {...props}/>}/>

Tenga en cuenta que uso render lugar de component . El motivo es evitar el desmontaje no deseado . También le paso los props a ese método, y uso los mismos apoyos en el componente Comentarios con el operador de propagación de objetos (propuesta ES7).


Para reaccionar enrutador 2.x.

const WrappedComponent = (Container, propsToPass, { children }) => <Container {...propsToPass}>{children}</Container>;

y en tus rutas ...

<Route path="/" component={WrappedComponent.bind(null, LayoutContainer, { someProp })}> </Route>

asegúrese de que el tercer parámetro sea un objeto como: { checked: false } .


Puede pasar props a través del <RouterHandler/> esta manera:

var Dashboard = require(''./Dashboard''); var Comments = require(''./Comments''); var Index = React.createClass({ render: function () { var props = this.props; // or possibly this.state return ( <div> <header>Some header</header> <RouteHandler {...props} /> </div> ); } });

La desventaja de esto es que estás pasando apoyos indiscriminadamente. Así que los Comments pueden 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 que los props son inmutables, pero esto puede ser problemático si dos componentes diferentes esperan un elemento llamado foo pero con valores diferentes.


Puede pasar props pasándolos a <RouteHandler> (en v0.13.x) o al componente Route en sí mismo en v1.0;

// v0.13.x <RouteHandler/> <RouteHandler someExtraProp={something}/> // v1.0 {this.props.children} {React.cloneElement(this.props.children, {someExtraProp: something })}

(de la guía de actualización en https://github.com/rackt/react-router/releases/tag/v1.0.0 )

Todos los manejadores de niños recibirán el mismo conjunto de accesorios, esto puede ser útil o no dependiendo de las circunstancias.


Sólo un seguimiento a la respuesta de ColCh. Es bastante fácil abstraer la envoltura de un componente:

var React = require(''react''); var wrapComponent = function(Component, props) { return React.createClass({ render: function() { return React.createElement(Component, props); } }); }; <Route path="comments" handler={wrapComponent(Comments, {myprop: value})}/>

No he probado esta solución todavía, por lo que cualquier comentario es importante.

Es importante tener en cuenta que con este método, todos los accesorios enviados a través del enrutador (como los parámetros) se sobrescriben o eliminan.


Si prefieres no escribir envoltorios, supongo que podrías hacer esto:

class Index extends React.Component { constructor(props) { super(props); } render() { return ( <h1> Index - {this.props.route.foo} </h1> ); } } var routes = ( <Route path="/" foo="bar" component={Index}/> );


También puede combinar funciones es6 y sin estado para obtener un resultado mucho más limpio:

import Dashboard from ''./Dashboard''; import Comments from ''./Comments''; let dashboardWrapper = () => <Dashboard {...props} />, commentsWrapper = () => <Comments {...props} />, index = () => <div> <header>Some header</header> <RouteHandler /> {this.props.children} </div>; routes = { component: index, path: ''/'', childRoutes: [ { path: ''comments'', component: dashboardWrapper }, { path: ''dashboard'', component: commentsWrapper } ] }


También puede usar la mezcla RouteHandler para evitar el componente de la envoltura y transmitir más fácilmente el estado del padre como accesorios:

var Dashboard = require(''./Dashboard''); var Comments = require(''./Comments''); var RouteHandler = require(''react-router/modules/mixins/RouteHandler''); var Index = React.createClass({ mixins: [RouteHandler], render: function () { var handler = this.getRouteHandler({ myProp: ''value''}); return ( <div> <header>Some header</header> {handler} </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); });


Usando ES6 puedes simplemente hacer envoltorios de componentes en línea:

<Route path="/" component={() => <App myProp={someValue}/>} >

Si necesitas pasar niños:

<Route path="/" component={(props) => <App myProp={someValue}>{props.children}</App>} >


Usando un componente de ruta personalizado , esto es posible en React Router v3.

var Dashboard = require(''./Dashboard''); var Comments = require(''./Comments''); var routes = ( <Route path="/" handler={Index}> <MyRoute myprop="value" path="comments" handler={Comments}/> <DefaultRoute handler={Dashboard}/> </Route> );

En cuanto al código del componente <MyRoute> , debería ser algo como:

import React from ''react''; import { Route } from ''react-router''; import { createRoutesFromReactChildren } from ''react-router/lib//RouteUtils''; const MyRoute = () => <div>&lt;MyRoute&gt; elements are for configuration only and should not be rendered</div>; MyRoute.createRouteFromReactElement = (element, parentRoute) => { const { path, myprop } = element.props; // dynamically add crud route const myRoute = createRoutesFromReactChildren( <Route path={path} />, parentRoute )[0]; // higher-order component to pass myprop as resource to components myRoute.component = ({ children }) => ( <div> {React.Children.map(children, child => React.cloneElement(child, { myprop }))} </div> ); return myRoute; }; export default MyRoute;

Para obtener más detalles sobre el enfoque del componente de ruta personalizado, consulte la publicación de mi blog sobre el tema: http://marmelab.com/blog/2016/09/20/custom-react-router-component.html


Utilice el componente con o sin enrutador basado en la respuesta de Rajesh Naroth.

class Index extends React.Component { constructor(props) { super(props); } render() { const foo = (this.props.route) ? this.props.route.foo : this.props.foo; return ( <h1> Index - {foo} </h1> ); } } var routes = ( <Route path="/" foo="bar" component={Index}/> );

O puedes hacerlo de esta manera:

export const Index = ({foo, route}) => { const content = (foo) ? foo : (route) ? route.foo : ''No content found!''; return <h1>{content}</h1> };


para el react-router 2.5.2, la solución es muy fácil:

//someConponent ... render:function(){ return ( <h1>This is the parent component who pass the prop to this.props.children</h1> {this.props.children && React.cloneElement(this.props.children,{myProp:''value''})} ) } ...


ACTUALIZACIÓN desde la nueva versión, es posible pasar props directamente a través del componente Route , sin usar un Wrapper

Por ejemplo, mediante el uso de prop prop. Enlace al router de reacción: https://reacttraining.com/react-router/web/api/Route/render-func

Ejemplo de código en codesandbox: https://codesandbox.io/s/z3ovqpmp44

Componente

class Greeting extends React.Component { render() { const { text, match: { params } } = this.props; const { name } = params; return ( <React.Fragment> <h1>Greeting page</h1> <p> {text} {name} </p> </React.Fragment> ); } }

Y uso

<Route path="/greeting/:name" render={(props) => <Greeting text="Hello, " {...props} />} />

VERSIÓN ANTIGUA

Mi forma preferida es envolver el componente Comments y pasar el envoltorio como un controlador de ruta.

Este es tu ejemplo con los cambios aplicados:

var Dashboard = require(''./Dashboard''); var Comments = require(''./Comments''); var CommentsWrapper = React.createClass({ render: function () { return ( <Comments myprop="myvalue" /> ); } }); var Index = React.createClass({ render: function () { return ( <div> <header>Some header</header> <RouteHandler /> </div> ); } }); var routes = ( <Route path="/" handler={Index}> <Route path="comments" handler={CommentsWrapper}/> <DefaultRoute handler={Dashboard}/> </Route> ); ReactRouter.run(routes, function (Handler) { React.render(<Handler/>, document.body); });


Solución React Router v 4

Me topé con esta pregunta hoy más temprano, y aquí está el patrón que utilizo. 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. Normalmente 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:

import React from ''react'' import { Route } from ''react-router-dom'' const getLocationAwareComponent = (component) => (props) => ( <Route render={(routeProps) => React.createElement(component, {...routeProps, ...props})}/> ) export default getLocationAwareComponent

Luego, en el archivo en cuestión, haré lo siguiente:

import React from ''react'' import someComponent from ''components/SomeComponent'' import { getLocationAwareComponent } from ''components/Core/getLocationAwareComponent'' const SomeComponent = getLocationAwareComponent(someComponent) // in render method: <SomeComponent someProp={value} />

Notarás que importo la exportación predeterminada de mi componente como humilde camel-case, que me permite nombrar el nuevo componente que tiene en cuenta la ubicación en CamelCase para que pueda usarlo normalmente. Aparte de la línea de importación adicional y la línea de asignación, el componente se comporta como se espera y recibe todos sus accesorios normalmente, con la adición de todos los accesorios de ruta. Por lo tanto, puedo redirigir felizmente los métodos del ciclo de vida de los componentes con this.props.history.push (), verificar la ubicación, etc.

¡Espero que esto ayude!