React doesn't reload component data on route param change or query change
Along with componentDidMount
, You also need to implement the componentWillReceiveProps
or use getDerivedStateFromProps
(from v16.3.0 onwards) in Products
page since the same component is re-rendered
with updated params
and not re-mounted
when you change the route params, this is because params are passed as props to the component and on props change, React components re-render and not re-mounted.
EDIT: from v16.3.0 use getDerivedStateFromProps
to set/update state based on props(no need to specify it in two different lifecyle methods)
static getDerivedStateFromProps(nextProps, prevState) { if (nextProps.match.params.product !== prevState.currentProductId){ const currentProductId = nextProps.match.params.product const result = productlist.products.filter(obj => { return obj.id === currentProductId; }) return { product: result[0], currentId: currentProductId, result } } return null;}
Prior v16.3.0, you would use componentWillReceiveProps
componentWillReceiveProps(nextProps) { if (nextProps.match.params.product !== this.props.match.params.product) { const currentProductId = nextProps.match.params.product const result = productlist.products.filter(obj => { return obj.id === currentProductId; }) this.setState({ product: result[0], currentId: currentProductId, result }) } }
As Product component is already loaded it will not reload. You have to handle new product id in the below method of component
componentWillReceiveProps(nextProps) {if(nextProps.match.params.name.product == oldProductId){ return;}else { //fetchnewProduct and set state to reload}
With latest version of react(16.3.0 onwards)
static getDerivedStateFromProps(nextProps, prevState){ if(nextProps.productID !== prevState.productID){ return { productID: nextProps.productID}; } else { return null; }}componentDidUpdate(prevProps, prevState) { if(prevProps.productID !== this.state.productID){ //fetchnewProduct and set state to reload }}
Although all the above-mentioned ways will work, I don't see a point to use getDerivedStateFromProps
. Based on React docs, "if you want to re-compute some data only when a prop changes, use a memoization helper instead".
Here, instead, I would suggest simply using componentDidUpdate
along with changing the Component
to PureComponenet
.
With reference to React docs, PureComponenet
s only rerender if at least one state or prop value changes. Change is determined by doing a shallow comparison of state and prop keys.
componentDidUpdate = (prevProps) => { if(this.props.match.params.id !== prevProps.match.params.id ) { // fetch the new product based and set it to the state of the component }; };
Please note that the above only work if you change the Component to PureComponent, and obviously, you need to import it from React.