Doxmare
Doxmare

Reputation: 61

ReactJS - Re-render same component when navigate back

I have a URL structure like

foo.com/details/:id

and using ReactRouter with it. If you search for an ID '123' the component renders the specific information from a database and updates the URL to

foo.com/details/123

If you search for another ID '456', the URL gets updated to

foo.com/details/456

with this.props.history.push(${this.state.id});

in short words - the component re-renders. If you reload or go directly to an ID with a URL the parameter works just as expected. Here is my question though: if you press the back button in the browser, the URL gets updated properly (456 => 123), but the component does not re-render.

How can I force the component to re-render when the URL param changes?

EDIT: more code

In the constructor:

 if (this.props.match.params.id !== undefined) {
            this.state.id = this.props.match.params.id;
            this.getData(this.state.id)
}

In the class:

 <form onSubmit={this.handleSubmit}>
  <input type="text" className="form-control mx-sm-3 mb-2" placeholder="Enter ID"value=             
         {this.state.id} onChange={this.handleChange}/>
  <input type="submit" value="Search" className="btn btn-primary mb-2"/>
</form>

handleChange(event) {
      this.setState({id: event.target.value})
}

handleSubmit(event) {
      this.props.history.push(`${this.state.id}`);
      this.getData(this.state.id);
      event.preventDefault();
}

Upvotes: 3

Views: 8685

Answers (2)

Shubham Gupta
Shubham Gupta

Reputation: 2646

Component doesn't rerender when the props change. So when a component is already mounted with id as 123 and you update id to 456 rerender won't trigger. You will have to trigger the update by updating the state. I suggest you to use componentDidUpdate instead of componentWillReceiveProps since it is marked as UNSAFE which means it might be deprecated in coming versions of React. You can componentDidUpdate or componentShouldUpdate. Following is implementation using componentDidUpdate.

componentDidUpdate(prevProps, prevState) {
  if (this.props.match.params.id !== prevProps.match.params.id) { 
     this.setState({ id: this.props.match.params.id}); 
     this.getData(this.props.match.params.id);
    // or any other logic..
  }
}

Upvotes: 2

Panther
Panther

Reputation: 9408

When the url point to the same component, the component does not gets unmounted and re-mounted, instead the same component with different props is passed to it. There are few ways to achieve the desired behaviour here.

  1. If you are able to specify a key(use ID) on the root element that is mounted.(The key should be on the element that makes use of the Id and does something and not with in it). If you cannot find a correct element to achieve this, move on to next one.

  2. Make use of componentWillReceiveProps and compare the nextProps id and currentProp id and write a logic to re-initailize the component for the new ID.

    componentWillReceiveProps(nextProps) {
     if (this.props.id !== nextProps.id) {
       // write your logic to update the component with new ID 
     }
    }
    

Upvotes: 0

Related Questions