DEV Community

Paramanantham Harrison
Paramanantham Harrison

Posted on • Originally published at learnwithparam.com

Dynamic pages in react router

Follow me on Twitter, happy to take your suggestions on topics or improvements

In part 1, we learned how to create basic static pages in react router. Now we are going to learn how to create dynamic URLs in react router.

We are going to create two routes,

  • Users Route (static routes to display all links to individual users)
  • User Route - Each user will be identified by their unique ID and the URL will pass this ID and the component will display the proper user content

Let's create a dummy users data

const users = [
  {
    name: `Param`,
  },
  {
    name: `Vennila`,
  },
  {
    name: `Afrin`,
  },
];
Enter fullscreen mode Exit fullscreen mode

Let's create new routes for all users and single user in our App.js file.

// App.js
...

const UsersPage = () => {
  return (
    <h3>Users Page</h3>
  );
};

const App = () => {
  return (
    <section className="App">
      <Router>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
        <Link to="/users">Users</Link>
        <Route exact path="/" component={IndexPage} />
        <Route exact path="/users" component={UsersPage} />
        <Route exact path="/about" component={AboutPage} />
      </Router>
      <a href="/about">about with browser reload</a>
    </section>
  );
};

...
Enter fullscreen mode Exit fullscreen mode

We have created a link to users page and also the route definition for users page along with its associated component (UsersPage).

Let's add links to each user in the UsersPage (/user/1, /user/2, /user/3)

// userId will be Array index + 1
const UsersPage = () => {
  return (
    <>
      <h3>Users Page</h3>
      {users.map((user, index) => (
        <h5 key={index}>
          <Link to={`/user/${index + 1}`}>{user.name}'s Page</Link>
        </h5>
      ))}
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

<></> this is short form for <React.Fragment></React.Fragment>. You can read more about fragments here

Now we have the users page with links. If you click on the link, it will lead to no page because we didn't create a route definition for each user.

We can create each separate route definition like this

<Route exact path="/user/1" component={UserPage1} />
<Route exact path="/user/2" component={UserPage2} />
Enter fullscreen mode Exit fullscreen mode

NO! 😱. I am just lying, we all know, this won't scale for dynamic pages with more dynamic data. Let's see how to create dynamic route definitions in react router. It's very easy.

<Route path="/user/:userId" component={UserPage} />
Enter fullscreen mode Exit fullscreen mode

Here :userId is the dynamic route params in the route definition. It get passed to the component. You can get access to the props called userId in UserPage component.

Let's add this code in our example.

// App.js
...

const UserPage = () => {
  return (
    <h3>User Page</h3>
  );
};

const App = () => {
  return (
    <section className="App">
      <Router>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
        <Link to="/users">Users</Link>
        <Route exact path="/" component={IndexPage} />
        <Route exact path="/users" component={UsersPage} />
        <Route exact path="/user/:userId" component={UserPage} />
        <Route exact path="/about" component={AboutPage} />
      </Router>
      <a href="/about">about with browser reload</a>
    </section>
  );
};

...
Enter fullscreen mode Exit fullscreen mode

Now our user page URL is working. But the page doesn't display any information about the user. Let's display the information.

How to get access to the route params in the component

React router pass two props to all the component

  • match props
  • location props

Let's just check what information those props have by consoling it in the component

// App.js

const UserPage = ({ match, location }) => {
  return (
    <>
      <p>
        <strong>Match Props: </strong>
        <code>{JSON.stringify(match, null, 2)}</code>
      </p>
      <p>
        <strong>Location Props: </strong>
        <code>{JSON.stringify(location, null, 2)}</code>
      </p>
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

Now let's see what those props have,

/*
  URL: /user/1
  userId: 1
*/

// Match Props
{ "path": "/user/:userId", "url": "/user/1", "isExact": true, "params": { "userId": "1" } }

// Location Props
{ "pathname": "/user/1", "search": "", "hash": "", "key": "7e6lx5" }
Enter fullscreen mode Exit fullscreen mode

If we closely look at the content, our interested userId params is in match.params.userId.

Let's use the params in the UserPage component and display information about the User.

...

// Getting the userId from match props and display the user from the users array
const UserPage = ({ match, location }) => {
  const { params: { userId } } = match;

  return (
    <>
      <p>
        <strong>User ID: </strong>
        {userId}
      </p>
      <p>
        <strong>User Name: </strong>
        {users[userId - 1].name}
      </p>
    </>
  );
};

...
Enter fullscreen mode Exit fullscreen mode


// Object destructuring in JavaScript
const {
  params: { userId },
} = match;
Enter fullscreen mode Exit fullscreen mode

We have used object destructuring in the code. You can read more about it here

That's it, folks. We have successfully finished developing dynamic routes and know how to access the route params in the component for dynamic routes. Hope you are enjoying this series, stay tuned for more advanced features 🤗

You can check out the codebase for this series here and the code for this section here

Discussion (0)