I have a react app with two pages--- the home and trip page. The trip page is rendered with the tripID passed in through the url. My app.js looks like :
function App() {
return (<>
<ThemeProvider theme={theme}>
<Router>
<Routes>
<Route exact path='/' element={<Home />} />
<Route path='/trip/:tripId' element={<TripComponent />} />
</Routes>
</Router>
</ThemeProvider>
</>
);
}
I have a global navbar with a menu of different tripIds
as many Link
to navigate to the TripComponent. When i am at the "/"
path, and I navigate to "/trip/tripA"
, i have no problems. But when i am at "/trip/tripA"
, and i want to navigate to "/trip/tripB"
, it doesnt work. I can see the url changing accordingly, but my TripComponent
doesnt rerender with tripB's data. the code for my menu in my navbar looks like:
ReactDOM.createPortal(<>
<CustomModal setOpen={setShowTripList} title={"Saved Trips"}>
<List>
{trips && trips.length > 0 &&
trips.map((trip, index) => {
return (
<Link to={`/trip/${trip._id}`} >
<ListItemButton>
<ListItemText id={trip._id} primary={trip.title} />
</ListItemButton>
</Link>
)
})
}
</List>
</CustomModal>
</>
, document.getElementById("portal"))
I am confused as to why this is happening. When i press the Link
to navigate to another URL, shouldn't it unmount and remount?
CodePudding user response:
When the tripId
route path parameter updates the routed element TripComponent
isn't remounted, it is only rerendered. If there is some logic that depends on the tripId
path parameter then TripComponent
needs to "listen" for changes to that value. This is the same thing that would need to happen if a prop value changed.
Use a useEffect
hook with a dependency on the tripId
path parameter to issue side-effects based on the current value.
Example:
import { useParams } from 'react-router-dom';
...
const TripComponent = () => {
const { tripId } = useParams();
useEffect(() => {
// initial render or tripId updated
// do something with current tripId value
}, [tripId]);
...
};
CodePudding user response:
I think the @Drew's answer is perfect. But I'd like to put something additionally.
I suggest you to use useMemo hook.
...
const trip = useMemo(() => {
// something you want
}, [tripId])
...