Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect URL parameter change in React

Tags:

reactjs

React is not detecting when the last parameter in the url changes. if I reload the page it works.

I´m using "react-router-dom": "^5.0.1"

the "router"

<Router>
    <PrivateRoute path="/users/:id" exact strict component={User}/>
</Router>

then. inside the User component I have a list of users and the details of the selected user

class User extends Component {

    constructor(props) {
        super(props);

        this.state = {
            userId: null,
            users: [{id: '1', name: 'john'}, {id: '2', name: 'mary'}]
        }
    }

    componentDidMount() {
        const { id } = this.props.match.params;
        this.setState({'userId': id})
    }

    render() {
        return (
            <div>
                <div className="users">
                    {this.state.users.map((user, index) => {
                        return (<Link to={`users/${user.id}`}  key={index}>{user.name}</Link>)      
                    })}
                </div>
                <pre className="details">{this.state.userId}</pre>          

            </div>
        )
    }

}

export default User;

when I select a different user the url changes but this.state.userid remains the same

UPDATE:

I resolved it with

componentWillReceiveProps(nextProps) {
    const { id } = nextProps.match.params;
    this.setState({'userId': id}
}

but I´m getting this warning.

Warning: componentWillReceiveProps has been renamed, and is not recommended for use.

React Hooks or die ?

like image 640
handsome Avatar asked May 17 '26 09:05

handsome


1 Answers

ComponentDidMount is called once (when the component mounts), so if does not matter if you change the route, the lifecycle will not be called again.

In order to achieve what you want I recommend you to use another lifecycle like (ComponentDidUpdate or getDerivedStateFromProps) or start using hooks, in your case useEffect. Or if it is simple, use the prop directly in the render method.

UPDATE:

This should do the trick:

  componentDidUpdate(prevProps) {
    if (this.state.userId !== this.props.match.params.id) {
      this.setState({ userId: this.props.match.params.id });
    }
  }

componentDidUpdate componentDidUpdate is still safe to use and is invoked immediately after updating occurs.

like image 53
Jaime Noel Alvarez Luna Avatar answered May 20 '26 01:05

Jaime Noel Alvarez Luna



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!