Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React router and this.props.children - how to pass state to this.props.children

I'm using React-router for the first time and I don't know how to think in it yet. Here's how i'm loading my components in nested routes.

entry point .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>     );   } 

So the child of my App is the Content component I sent in. I'm using Flux and my App.js has the state and listens for changes, but I don't know how to pass that state down to this.props.children. Before using react-router my App.js defines all children explicitly, so passing state was natural but I don't see how to do it now.

like image 913
Patrick Avatar asked Mar 07 '16 03:03

Patrick


People also ask

How do you pass router props to child component React?

But how would you pass props to the child component in React Router? You can use the render prop instead of the component prop for passing props to the child component. The route props include match, location, and history which are used to get the current route state from React Router within your component.

Can you pass props through React router?

With the react-router v5, we can create routes by wrapping with a component, so that we can easily pass props to the desired component like this.

Can you pass state through props React?

Passing state as props from parent to child components is a core concept of React. By keeping state in only a few components and passing it to as many children as needed in the form of props, you will be able to write code that is easier to maintain, and you will thank yourself down the road.


1 Answers

This question boils down to, how do you pass props to children?

June 2018 answer

Today's tech:

  • React 16+
  • React Router 4: react-router-dom
  • Render Props from official docs

Assuming some stateful component:

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>     )   } } 

This works because this.props.children is a function:

// "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> ) 

Example on codesandbox

My previous oldschool answer that I wouldn't recommend anymore:

Using a couple of React helper methods you can add state, props and whatever else to 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> } 

Then your child component can access this via props, this.props.foo.

like image 121
azium Avatar answered Sep 19 '22 09:09

azium