switch source react link example doom reactjs react-router

reactjs - source - react router switch



Reaccionar router y this.props.children-cómo pasar el estado a this.props.children (3)

Estoy usando React-router por primera vez y todavía no sé cómo pensarlo. Así es como estoy cargando mis componentes en rutas anidadas.

punto de entrada .js

ReactDOM.render( <Router history={hashHistory} > <Route path="/" component={App}> <Route path="models" component={Content}> </Route> </Router>, document.getElementById(''app'') );

App.js

render: function() { return ( <div> <Header /> {this.props.children} </div> ); }

Entonces, el hijo de mi aplicación es el componente de contenido que envié. Estoy usando Flux y mi App.js tiene el estado y escucha los cambios, pero no sé cómo pasar ese estado a this.props.children . Antes de usar reaccionar-enrutador, mi App.js define explícitamente a todos los niños, por lo que pasar el estado era natural, pero no veo cómo hacerlo ahora.


Esta pregunta se reduce a, ¿cómo pasas los accesorios a los niños?

Respuesta de junio de 2018

La tecnología de hoy:

Asumiendo algún componente con estado:

import React from ''react'' import { BrowserRouter, Route } from ''react-router-dom'' // some component you made import Title from ''./Title'' class App extends React.Component { // this.state state = { title: ''foo'' } // this.render render() { return ( <BrowserRouter> // when the url is `/test` run this Route''s render function: <Route path="/:foobar" render={ // argument is props passed from `<Route /`> routeProps => // render Title component <Title // pass this.state values title={this.state.title} // pass routeProps values (url stuff) page={routeProps.match.params.foobar} // "test" /> } /> </BrowserRouter> ) } }

Esto funciona porque this.props.children es una función:

// "smart" component aka "container" class App extends React.Component { state = { foo: ''bar'' } render() { return this.props.children(this.state.foo) } } // "dumb" component aka "presentational" const Title = () => ( <App> {title => <h1>{title}</h1>} </App> )

Ejemplo en codesandbox

Mi vieja respuesta anterior que ya no recomendaría:

Usando un par de métodos React helper puedes agregar state, props y cualquier otra cosa a this.props.children

render: function() { var children = React.Children.map(this.props.children, function (child) { return React.cloneElement(child, { foo: this.state.foo }) }) return <div>{children}</div> }

Entonces su componente hijo puede acceder a esto a través de accesorios, this.props.foo .


Puede usar el método Reaccionar "cloneElement" para lograr esto. Cuando clonas el elemento, puedes pasar accesorios en ese momento. Usa el clon en lugar del original en tu render fn. p.ej:

render: function() { var childrenWithProps = React.cloneElement(this.props.children, {someProp: this.state.someProp}); return ( <div> <Header /> {childrenWithProps} </div> ); }


También existe la opción de usar Context . React-Router se basa en él para dar acceso al objeto Router en los componentes de la ruta.

De otra answer que di sobre una pregunta similar:

Rápidamente codepen un ejemplo usando contextos en codepen . MainLayout define algunas propiedades que podrían usar los niños que usan el contexto: users y widgets . Estas propiedades son utilizadas por los componentes UserList y WidgetList . Tenga en cuenta que necesitan definir a qué necesitan acceder desde el contexto en el objeto contextTypes .

var { Router, Route, IndexRoute, Link } = ReactRouter var MainLayout = React.createClass({ childContextTypes: { users: React.PropTypes.array, widgets: React.PropTypes.array, }, getChildContext: function() { return { users: ["Dan", "Ryan", "Michael"], widgets: ["Widget 1", "Widget 2", "Widget 3"] }; }, render: function() { return ( <div className="app"> <header className="primary-header"></header> <aside className="primary-aside"> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/users">Users</Link></li> <li><Link to="/widgets">Widgets</Link></li> </ul> </aside> <main> {this.props.children} </main> </div> ) } }) var Home = React.createClass({ render: function() { return (<h1>Home Page</h1>) } }) var SearchLayout = React.createClass({ render: function() { return ( <div className="search"> <header className="search-header"></header> <div className="results"> {this.props.children} </div> <div className="search-footer pagination"></div> </div> ) } }) var UserList = React.createClass({ contextTypes: { users: React.PropTypes.array }, render: function() { return ( <ul className="user-list"> {this.context.users.map(function(user, index) { return <li key={index}>{user}</li>; })} </ul> ) } }) var WidgetList = React.createClass({ contextTypes: { widgets: React.PropTypes.array }, render: function() { return ( <ul className="widget-list"> {this.context.widgets.map(function(widget, index) { return <li key={index}>{widget}</li>; })} </ul> ) } }) var Routes = React.createClass({ render: function() { return <Router> <Route path="/" component={MainLayout}> <IndexRoute component={Home} /> <Route component={SearchLayout}> <Route path="users" component={UserList} /> <Route path="widgets" component={WidgetList} /> </Route> </Route> </Router>; } }) ReactDOM.render(<Routes/>, document.getElementById(''root''))