11

I have a React application that uses URL search params. Depending on the value of the search parameter v, the component is supposed to show different content.

A possible URL might look like this:

http://localhost:3000/hello?v=12345

Once the v query parameter changes in the URL, I would like my component to update.

http://localhost:3000/hello?v=6789

I'm using using react-router in my App component to display the different components depending on the route. The App component is wrapped into a BrowserRouter component.

render() {
  return (
    <Switch>
      <Route path="/hello" component={Hello}></Route>
      <Route path="/" component={Home}></Route>
    </Switch>
  );
}

If a user clicks on something and the URL search param v changes, I would like the component to display different content. Currently, the URL search param does change, but the component doesn't render again. Any ideas?

3 Answers 3

9

As @forJ correctly pointed out, the main idea is to make the component re render once the URL parameters change. I achieved it like so:

render() {
  return (
    <Switch>
      <Route path="/hello" render={() => (<Hello key={this.props.location.key}/>)}></Route>
      <Route path="/" component={Home}></Route>
    </Switch>
  );
}

this.props.location.key changes every time the URL changes (also if the query params change). So if you pass it as props to the component, then the component re renders on URL param changes, even though the base URL (the URL without the URL params) hasn't changed.

I also had to use the withRouter higher order component to make it work.

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Hello));
Sign up to request clarification or add additional context in comments.

3 Comments

The withRouter is critical here if you are using redux.
Using "key" will cause a full unmounting and remounting of the component so consider the negative performance implications. medium.com/@albertogasparin/…
I have no words to thank you. This Answer saved my week. Thanks for such a great solution.
2

If you use useEffect hook make sure to have [props.match.params] instead of empty array []

useEffect(() => {

        (async () => {
            // Fetch your data
        })();
    }, [props.match.params]) // <-- By this it will get called when URL changes

of course for class components this.props.match.params

Comments

1

You have not provided enough information so I cannot be 100% sure where you are going wrong but I can see 1 problem right now in your code. First, you have to let the router know that you will be using parameters. So for example below code

render() {
  return (
    <Switch>
      <Route path="/hello/:yourParam" component={Hello}></Route> // you need the colon here
      <Route path="/" component={Home}></Route>
    </Switch>
  );
}

The above will tell the route that parameter called yourParam will be accessible from the URL

Then it has to be accessed in your component and put into render function somehow (use it to retrieve data from database to render data, just render params directly, etc).

For example below

render(){
    <div>
        {this.props.match.params.yourParam}
    </div>
}

This way, your component will re-render everytime there is param change.

EDIT

Since you want to use query instead of parameter, you would have to retrieve it by going. this.props.match.query.v. You would still have to make sure that variable is rendered depending on query change

3 Comments

If I do '/hello/:yourParam', then my url looks like localhost:3000/hello/123, but I want it to use URL search parameters so that the URL looks like localhost:3000/hello?v=123
@slashburn. Sorry my bad. Then you would just have to check that you are retrieving the query from the class by going this.props.match.query.v and make sure render function re-runs on change of that value
Ah, I see. Thanks @forJ for pointing me into the right direction

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.