Reputation: 3452
I have the following two paths set up
<Route path="bookings/:bookingnumber" element={<Bookings />} />
<Route path="bookings" element={<Bookings />} />
In Bookings
component I have conditional code written to check if a parameter :bookingnumber
is passed, and then it only shows results relevant to that booking number.
Otherwise, if no parameter is passed, it shows all the results for all the bookings.
I am using Outlet
to display these components in the main area, and the two paths can be chosen from a sidebar.
Let's say I have 10 results
if I go to /bookings
, and 2 results
if I go to /bookings/123
.
However, if I go to /bookings/123
first and then to /bookings
it keeps on showing only 2 results
(the component does not reload, however I can see the URL changing in the browser)
Upvotes: 13
Views: 6034
Reputation: 61
ok, the solution is add a unique key property value to the component, for example:
<Route path="bookings/:bookingnumber" element={<Bookings key={"BookingsA"}/>} />
<Route path="bookings" element={<Bookings key={"BookingsB"} />} />
Upvotes: 0
Reputation: 133
I've been struggling too with this issue, the solution is to add the key
prop, which is used by react to understand when 2 components are different (otherwise it assumes they're the same and they will not be re-rendered).
Hence the solution in your case may look like:
<Route key={'single'} path="bookings/:bookingnumber" element={<Bookings />} />
<Route key={'all'} path="bookings" element={<Bookings />} />
Upvotes: 7
Reputation: 202751
<Route path="bookings" element={<Bookings />} />
<Route path="bookings/:bookingnumber" element={<Bookings />} />
With the same component rendered on more than 1 route, if you navigate from one route to another for the same routes component, the routed component remains mounted.
Example: If navigating from "/bookings"
to "/bookings/123"
, or "/bookings/123"
to "/bookings"
, or "/bookings/123"
to "/bookings/456"
the Bookings
component remains mounted. If you've any logic that depends on the bookingnumber
route path parameter then the Bookings
component needs to handle this in a useEffect
hook with a proper dependency on the bookingnumber
param.
Use a useEffect
hook to "listen" for changes to the bookingnumber
param value.
Example:
const Bookings = () => {
const { bookingnumber } = useParams();
useEffect(() => {
// initial render or booking number value updated
// run logic depending on bookingnumber value to update "results"
...
}, [bookingnumber]);
...
};
Upvotes: 9
Reputation: 683
Hello I believe you are using react-router-dom v6
, in this case you can wrap the child routes inside your main path route. And then give them the index(true|false)
attribute to make sure the router understand if it is the exact index page or should render a page based on params.
Note: I copied the example from above, and added some lines to fix it!
<Route path="bookings">
<Route index={false} path=":bookingnumber" element={<ViewBooking />} />
<Route index={true} element={<BookingList />} />
</Route>
UPDATE:
You can handle a single component route with useParams
hook.
Here what you're routing file should look like:
<Route path="bookings">
<Route index={false} path=":bookingnumber" element={<ViewBooking />} />
<Route index={true} element={<BookingList />} />
</Route>
And this is what your component should look like:
const MyComponent = () => {
const { bookingnumber } = useParams()
// if the path doesn't include the booking number then we should just render a normal page
if( !bookingnumber ) {
return <h1>This is a simple page</h1>
}
// if the page path does include the booking number then we can fetch data and return another result
// example you can fetch data based on this number
const [username, setUsername] = useState("")
useEffect(() => {
const fetchData = async () => {
const req = await fetch(`https://629c770de9358232f75b55dc.mockapi.io/api/v1/users/${bookingnumber}`)
const data = await req.json()
setUsername(data.name)
}
fetchData()
}, [username])
return (
<h1>Welcome mr.{username}</h1>
)
}
Upvotes: 1
Reputation: 365
<Route path="bookings" element={<BookingList />}>
<Route path=":bookingnumber" element={<ViewBooking />} />
</Route>
make two pages, first one will show all list of bookings and second one will show ID data
Upvotes: 1