I have a News
component that requires some props and I want to make it whenever I click on the <Link />
and the corresponding category prop Re-render. 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 mine <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> ); })}
P粉4768839862024-03-27 12:51:14
We can simply add a unique key
in the element
component. endcphpcn will be re-rendered each time with some different
props.
} />
P粉2427419212024-03-27 10:45:53
react-router
/react-router-dom
Optimizes rendering by keeping the same component instance installed, even if it renders on multiple routes. This is a performance optimization that saves you the process of uninstalling and reinstalling the same component just to pass different props values to it. In other words, the component remains mounted even if the route changes, and dependency props value updates should be handled in the componentDidUpdate
lifecycle method or the useEffect
hook.
Based on the routing and props being passed, this News
component does have some dependencies on the category
props, since that's the only prop I see that is different.
News
component should probably have a useEffect
hook and rely on this category
property to run/load any different data based on this different property value.
Example:
const News = ({ apiKey, category, country, pageSize }) => { useEffect(() => { // a dependency value changed, rerun some logic }, [apiKey, category, country, pageSize]); ... };
If News
is a component based on the React class, then it should implement the componentDidUpdate
method.
class News extends React.Component { ... componentDidUpdate(prevProps) { const { apiKey, category, country, pageSize } = this.props; if ( category !== prevProps.category /* || other props change conditions */ ) { // a dependency value changed, rerun some logic } } ... };
Additionally, based on this, since the category
and URL paths also seem to match, in most cases you can also make your code drier by rendering a single route using :Category as route path parameter and apply the same useEffect
hook logic to re-run logic that depends on the category value.
Example:
} />
import { useParams } from 'react-router-dom'; const News = ({ apiKey, country, pageSize }) => { const { category = "general" } = useParams(); useEffect(() => { // a dependency value changed, rerun some logic }, [apiKey, category, country, pageSize]); ... };
Similarly, if News
is a class component, use the appropriate componentDidUpdate
lifecycle methods and implement custom withRouter
higher-order components, so that category
route path parameters are injected as props.
Using React keys on the News
component should only be used as a last resort as it involves actual disassembly, such as unmounting and remounting the component, This requires more work than simply re-rendering the component with updated prop values.