Navigating between multiple params - React js

Viewed 87

So I've been working on a project lately using React js (I thought it would be similar to React native), while I pretty much understand most of it as I previously worked with React native a lot. There are still some new things I'm learning for example the react-router-dom npm. So I understand the basics and how it works, but I'm trying to use parameters which change depending on the user (User ID).

The code below shows how I'm currently using my router. While going to home (/) and /user/:id works, I can't go to /user/:id/settings. If I try going to the settings it renders both the /user/:id page and below it renders settings page.

What I want to be able to do is if the user is in the user/:id page they can click a button which takes them to the user/:id/settings instead of the current issue where it renders the setting page below the user page.

App.jsx

export class App extends React.Component {
    render() {
        return (
            <Router>
                <Route exact path="/" component={Home} />
                <Route path="/user/:id" component={User} />
                <Route path="/user/:id/settings" component={Setting} />
            </Router>
        )
    }
};

User.jsx

render() {
        return (
            <div>
                {/* Cool information about the user */}
                <div
                    className="optionContent"
                    onClick={() => {
                    let uri = `/user/${this.props.match.params.id}/settings`;
                    this.props.history.push(uri)
                }}
                >
                    Press me
                </div>
            </div>
        );
    }

Extra information:

  • I have tried using variable parameters for users but I wasn't able to full make those work as once the user enters /user/:id page the buttons update the url but not the parameters in this.
  • I need to have the ID within the url to fetch from the API and some other stuff

Variable url: /user/:id/:type?

1 Answers

This is because with React Router v5 which is currently the latest version as v6 is completed, the routes aren't exact by default which means that for each of the routes, if the current route starts with the route of a component, this component will be displayed.

For your example:

<Router>
    <Route exact path="/" component={Home} />
    <Route path="/user/:id" component={User} />
    <Route path="/user/:id/settings" component={Setting} />
</Router>

If the current route is "/user/user1" then it only matches the User component.

If the current route is "/user/user1/settings/ then it matches User and Settings components so they will both be rendered as you are finding.

To fix it, simply use the exact keyword on the component with the fewer requirements.

<Router>
    <Route exact path="/" component={Home} />
    <Route exact path="/user/:id" component={User} />
    <Route path="/user/:id/settings" component={Setting} />
</Router>
Related