How does react-router pass params to other components via props?

48,913

That is a question about react-router internals.

react-router is a React component itself and it uses props to pass all the routing information to the children components recursively. However, that is an implementation detail of react-router and i understand it can be confusing, so read on for more details.

The routing declaration in your example is:

<Router history={new HashHistory}>
  <Route path="/" component={Main}>
    <Route path = "topics/:id" component={Topic}></Route>
  </Route>
</Router>

So basically, React-Router will go through each of the components in the routing declaration (Main, Topic) and "pass" the following props to each of the components when the component is created using the React.createElement method. Here are all the props passed to each component:

const props = {
   history,
   location,
   params,
   route,
   routeParams,
   routes
}

The props values are computed by different parts of react-router using various mechanisms (e.g. extracting data from the URL string using regex expressions).

The React.createElement method itself allows react-router to create an element and pass the props above. The signature of the method:

ReactElement createElement(
  string/ReactClass type,
  [object props],
  [children ...]
)

So basically the call in the internal implementation looks like:

this.createElement(components[key], props)

Which means that react-router used the props defined above to initiate each of the elements (Main, Topic etc.), so that explains how you could access this.props.params in the Topic components itself, it was passed by react-router!

Share:
48,913
thetrystero
Author by

thetrystero

Updated on October 02, 2020

Comments

  • thetrystero
    thetrystero over 3 years

    Thus far, the extent of my knowledge about how properties are passed from one component to another via parameters is as follows

    //start: extent of my knowledge

    Suppose there exists some state variable called topic in A.jsx. I want to pass this down to B.jsx, so I perform the following

    B = require('./B.jsx')
    getInitialState: function() {return {topic: "Weather"}}
    <B params = {this.state.topic}>
    

    In B.jsx I can then do stuff like

    module.exports = React.createClass({
    render: function() {
       return <div><h2>Today's topic is {this.props.params}!</h2></div>
    }
    })
    

    which when called upon will render "Today's topic is Weather!"

    //end: extent of my knowledge

    Now, I'm going through a tutorial on react-router with the following code snippets

    topic.jsx:

    module.exports = React.createClass({
      render: function() {
        return <div><h2>I am a topic with ID {this.props.params.id}</h2></div>
        }
      })
    

    routes.jsx:

    var Topic = require('./components/topic');
    module.exports = (
      <Router history={new HashHistory}>
        <Route path="/" component={Main}>
          <Route path = "topics/:id" component={Topic}></Route>
        </Route>
    
      </Router>
    )
    

    header.jsx:

      renderTopics: function() {
        return this.state.topics.map(function(topic) {
          return <li key = {topic.id} onClick={this.handleItemClick}>
            <Link to={"topics/" + topic.id}>{topic.name}</Link>
          </li>
        })
      }
    

    where this.state.topics is a list of topics drawn from the imgur API via Reflux.

    My question is: by what mechanism is params passed in to props for topic.jsx? Nowhere in the code do I see an idiom as expressed in the above section on the "extent of my knowledge" viz. there is no <Topic params = {this.state.topics} /> in either routes.jsx or header.jsx. Link to the full repo here. React-router docs says that params is "parsed out of the original URL's pathname". This did not resonate with me.

  • thetrystero
    thetrystero over 8 years
    thanks for this answer. i'm always curious how one goes about digging under the hood for such things. was this by experience, or did you find it in the docs? if so can you please point me to the exact location?
  • Faris Zacina
    Faris Zacina over 8 years
    I just digged through the implementation at: github.com/rackt/react-router/tree/master/modules
  • Anil
    Anil almost 7 years
    its working fine but on that url my all links and scripts become 404. Please help