Re-render React component when prop changes
You have to add a condition in your componentDidUpdate
method.
The example is using fast-deep-equal
to compare the objects.
import equal from 'fast-deep-equal'...constructor(){ this.updateUser = this.updateUser.bind(this);} componentDidMount() { this.updateUser();}componentDidUpdate(prevProps) { if(!equal(this.props.user, prevProps.user)) // Check if it's a new user, you can also use some unique property, like the ID (this.props.user.id !== prevProps.user.id) { this.updateUser(); }} updateUser() { if (this.props.isManager) { this.props.dispatch(actions.fetchAllSites()) } else { const currentUserId = this.props.user.get('id') this.props.dispatch(actions.fetchUsersSites(currentUserId)) } }
Using Hooks (React 16.8.0+)
import React, { useEffect } from 'react';const SitesTableContainer = ({ user, isManager, dispatch, sites,}) => { useEffect(() => { if(isManager) { dispatch(actions.fetchAllSites()) } else { const currentUserId = user.get('id') dispatch(actions.fetchUsersSites(currentUserId)) } }, [user]); return ( return <SitesTable sites={sites}/> )}
If the prop you are comparing is an object or an array, you should use useDeepCompareEffect
instead of useEffect
.
ComponentWillReceiveProps()
is going to be deprecated in the future due to bugs and inconsistencies. An alternative solution for re-rendering a component on props change is to use ComponentDidUpdate()
and ShouldComponentUpdate()
.
ComponentDidUpdate()
is called whenever the component updates AND if ShouldComponentUpdate()
returns true (If ShouldComponentUpdate()
is not defined it returns true
by default).
shouldComponentUpdate(nextProps){ return nextProps.changedProp !== this.state.changedProp;}componentDidUpdate(props){ // Desired operations: ex setting state}
This same behavior can be accomplished using only the ComponentDidUpdate()
method by including the conditional statement inside of it.
componentDidUpdate(prevProps){ if(prevProps.changedProp !== this.props.changedProp){ this.setState({ changedProp: this.props.changedProp }); }}
If one attempts to set the state without a conditional or without defining ShouldComponentUpdate()
the component will infinitely re-render
You could use KEY
unique key (combination of the data) that changes with props, and that component will be rerendered with updated props.