How to pass props to a component rendered by React Router v4

Note in this post I am using React Router v4.

We have seen several examples and use cases in react-router. One among them is passing props to the route component directly. React Router v4 uses a declarative, component-based approach for routing. It means when you want to create a new route, and you render a Route component.

It is straightforward to achieve in react-router, let us create a new route for passing props to the component. For example, suppose we wanted to render the Home component whenever a user navigates to the / path. To do that, we'd render a Route that looks like this.

<Route path="/" component={Home} />

Now, let's say we want to pass a prop named name to the Home component. There are multiple different ways to solve this problem but only one right way. The first idea you might have is to pass it as a prop on Route like we usually do for the component.

<Route path="/" component={Home} name={"Pratap"} />

Unfortunately, the above approach won't work it is because React Router does not forward any prop onto the component. Instead, it will just ignore it.

The next approach you might think of is a pattern which a few people follow is to pass a component an inline function which creates the React element.

Using the code snippet below, you can pass props to the component by making use of the render prop passing an inline function to the component definition of the Route.

<Route path="/" component={() => <Home name={"Pratap"} />} />

The above approach will work, but it is not the recommended way by react-router. Why? Because

  • Using component, the react-router uses React.createElement to create a new React element. Providing an inline function to the component would create a new component in every render which results in the existing component unmounting and the new component mounting instead of just updating the existing component.
  • For large apps with multiple state changes within the page, it degrades the performance of the page due to unnecessary re-rendering.

So if you're not supposed to pass an inline function to a component, then what's the solution?

React router provides an easy solution for this case. Instead of passing function through component props, we can pass it through render props.

Make sure that you are passing {...props} as this will make sure all the default router props like location, match, history etc. are getting passed on to the Home component. Else the only prop that will be passed down to it is name.

While passing our own props, we also need to pass the default props send to the render props by react router. Lets see it in our example,

<Route path="/" render={(props) => <Home {...props} name={"Pratap"} />} />

The above approach is the recommended way to pass props in react-router.

Let us see how our App.js file looks like after the last change.

import React from "react";
import ReactDOM from "react-dom";
import { Link, BrowserRouter as Router, Route, Switch } from "react-router-dom";

const App = () => {
  return (
    <div>
      <Router>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
        <Switch>
          <Route
            exact
            path="/"
            render={(props) => <Home {...props} name="Pratap" />}
          />

          {/* Not a recommended approach */}
          <Route
            exact
            path="/about"
            component={() => <About title="This is about Page" />}
          />
        </Switch>
      </Router>
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Accessing the prop in the component

We can access the props name using the following snippet.

import React from "react";

const Home = ({ name }) => {
  return <div>I am home component passed by {name}</div>;
};

export default Home;

To sum it up

So to sum it up, if you need to pass any props to a component rendered by React Router v4, instead of using Routes component prop and passing an inline function, use its render prop. With render prop, you're in charge of creating the element and can pass the component any number of props you'd like.

💌 If you'd like to receive more tutorials in your inbox, you can sign up for the newsletter here.

Please don't hesitate to drop a comment here if I miss anything. Also, let me know if I can make the post better.

Discussions

Up next