Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React router: component not updating on url search param change

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?

like image 759
productioncoder Avatar asked Jun 03 '18 14:06

productioncoder


2 Answers

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));
like image 177
productioncoder Avatar answered Nov 14 '22 21:11

productioncoder


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

like image 39
forJ Avatar answered Nov 14 '22 22:11

forJ