1

We have a simple react app.. Data is coming from an api and stored in the state. Then we use a map function to render the data. And use sort and filter functions to manipulate the data.

Now, we are trying to associate the filter information with the URL by using the query string. So that, on sharing the page URL, filter data is also passed along with it.

We are updating the query string using the link tag of 'react-router-dom' library

<Link to='/pagePath?queryStringKey=queryStringValue'> Link Content </Link>

Now, how to listen to query string change? componentDidMount runs only once when the component is mounted. But when the query string is changed using the Link tag, componentDidMount do not run. And if we listen from render function then it gives this error.

Error: Maximum update depth exceeded. 

What is the right way to listen/detect the query string change?

Arpit Vyas
  • 2,118
  • 1
  • 7
  • 18
Jasmohan Singh
  • 61
  • 3
  • 11

2 Answers2

1

the reason you are getting that error is because you're listening in the render function. React mounts, renders, listens to the query string, re-renders again, remounts, re-listens etc. until you have exceeded the max update depth

if componentDidMount isn't working, consider using componentDidUpdate this will update every time the component updates

Red Baron
  • 7,181
  • 10
  • 39
  • 86
  • I tried componentDidUpdate as well. actually we need to update state when query string changes. And we got this error.Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method. – Jasmohan Singh Jun 16 '20 at 05:59
  • @JasmohanSingh what are you actually trying to do once you listen to the query params? – Red Baron Jun 16 '20 at 06:01
  • once there is a change in the query string, we want to filter or sort an array of objects stored in state. Basically we will manipulate the state on query string change. – Jasmohan Singh Jun 16 '20 at 06:04
  • are you able to produce a sandbox? I think it'll be easy to solve then – Red Baron Jun 16 '20 at 06:06
  • componentDidUpdate actually worked but I was updating state based on query string change. And componentDidUpdate runs on every render of the component. so I had to place a check on query string change. first I stored the query string in the state on componentDidMount. then I compared state value with a realtime value of query string in componentDidUpdate. And if values differed then I updated state value. So now I can update state on every query string change. Thanks for your suggestion. – Jasmohan Singh Jun 19 '20 at 04:51
  • glad to hear it worked! @JasmohanSingh . will upvote your question too – Red Baron Jun 19 '20 at 06:19
0

You can use getDerivedStateFromProps(props, state) and componentDidUpdate life cycle components. It accepts props and state as parameters. It is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing. enter link description here

constructor(){
  super();
  this.state = {
    queryStringKey = ''
  }
}

static getDerivedStateFromProps(props, state){
  let { queryStringKey } = this.props.match.params;
  if(queryStringKey !== state.queryStringKey){
    return {
      queryStringKey: props.queryStringKey
    }
  }

  return null;
}
Jeeva
  • 1,550
  • 12
  • 15