Dynamic pages in react router

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

Lets create a dummy users data

const users = [
  {
    name: `Param`,
  },
  {
    name: `Vennila`,
  },
  {
    name: `Afrin`,
  },
]

Lets create a 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>
  );
};

...

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

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

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

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

<Route path="/user/:userId" component={UserPage} />

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.

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

...

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

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

Now lets 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" }

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

Lets 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>
    </>
  );
};

...

https://codesandbox.io/s/p3ozwy018j

// Object destructuring in JavaScript
const {
  params: { userId },
} = match

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

Thats 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 checkout the codebase for this series here and the code for this section here

Beginners to ProNode Js

Visual Guide to API Design Best Practices

This visual eBook covers essential best practices for designing robust APIs using REST principles.

This book is ideal for beginners and backend developers seeking to enhance their API design skills. However, it is not suited for those seeking an in-depth exploration of API design. This book is a quick read under 40 slides like scrolling through your instagram feed.

Visual Guide to API Design Best Practices