I have a News
component which takes some props, and I want to make it re-render whenever I click on <Link />
with the corresponding category props. It updates the URL but does not re-render the component.
<Routes>
<Route
path="/"
element={
<News
country={this.country}
apiKey={this.API_KEY}
pageSize={this.pageSize}
category="general"
/>
}
/>
<Route
path="/business"
element={
<News
country={this.country}
apiKey={this.API_KEY}
pageSize={this.pageSize}
category="business"
/>
}
/>
<Route
path="/entertainment"
element={
<News
country={this.country}
apiKey={this.API_KEY}
pageSize={this.pageSize}
category="business"
/>
}
/>
</Routes>
These are my <NavLink />
<li className="nav-item">
<NavLink className="nav-link" aria-current="page" to="/">
Home
</NavLink>
</li>
{this.props.categories.map((category) => {
return (
<li key={category} className="nav-item">
<NavLink to={`/${category}`} className="nav-link">
{category[0].toUpperCase() +
category.slice(1, category.length)}
</NavLink>
</li>
);
})}
2
Answers
We can simply add a unique
key
in theelement
component. It willre-render
every time with some differentprops
.react-router
/react-router-dom
optimizes rendering by keeping the same component instance mounted even though it is rendered on multiple routes. This is a performance optimization to save unmounting and remounting the same component only to pass it different props values. In other words, the component remains mounted even though the route changed, and should handle the props value updating in thecomponentDidUpdate
lifecycle method oruseEffect
hook with dependency.Based on the routes and the passed props it’s really that this
News
component has some dependency on thecategory
prop as that’s the only prop I see that is different.The
News
component should likely have auseEffect
hook with a dependency on thiscategory
prop to run/load whatever data is different based on this different prop value.Example:
If
News
is a React class-based component then it should implement thecomponentDidUpdate
method.Also, based on this, since it also appears that the
category
and the URL path match, for the most part, you could likely also make the code more dry by rendering a single route with the category as a route path parameter, and applying the sameuseEffect
hook logic to rerun the logic that depends on the category value.Example:
Again, if
News
is a Class-component, then use the appropriatecomponentDidUpdate
lifecycle method and implement a customwithRouter
Higher Order Component in order to inject thecategory
route path parameter as a prop.Using a React key on the
News
component should only be used as a last resort since it invloves actually tearing down, e.g. unmounting, and remounting the component which is a lot more work than simply rerendering the component with updated prop values.