You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm trying to accomplish something with React Router that I don't think it supports (which would make this a feature request), but I'm not sure so I'm posting this in Q&A. I'm building a threaded messaging application that supports multiple groups. A single message can be sent to multiple groups. Currently, the thread view is modelled as it's own route, /threads/:threadId. A thread (e.g. ID 1) sent to groups 1 and 2 can be clicked on while browsing either group and the user will be redirected to /threads/1 for viewing the thread.
We've found that rendering the group view isn't quite as snappy as we'd like and this impacts the user when they close a thread and navigate back to whatever group they were originally viewing. There are several ways we could address this (e.g. update the group view to render it's list of threads using a virtual list or simply add more performance optimizations throughout the component tree), but the way we'd like to address this for the time being is to keep the group view in the DOM (i.e. keep the group view mounted) even while the user is viewing a thread. I.e. if the user is viewing a group and clicks on a thread, from their perspective it looks like they're navigated to a new page and the URL will update to /threads/:threadId, but in actuality the group will stay mounted in the background and the thread view will be rendered as a dialog on top of the group view. The group view will just be hidden with visibility: hidden. When the user closes the thread, we just close the thread dialog and show the group again with visibility: visible--which is very snappy (from an implementation perspective, there are some other benefits to this approach as well which I won't get into). If the user is viewing their inbox and clicks on a thread, then the URL will update to /threads/:threadId but in actuality the inbox will stay mounted in the background and the thread will just open in a dialog on top of the inbox. If someone were to navigate directly to a thread by updating the URL in their browser and hitting Enter, then we'll take them to their inbox and render the thread on top of it.
Essentially, the thread view is not a proper route. It's a virtual route. The proper routes would be /groups/:groupId or /inbox and the thread view is just a dialog rendered on top of it. But the thread view does update the URL. One response might be, why not have the URL be /groups/:groupId/thread/:threadId or /inbox/thread/:threadId? The answer is that our app is multiplayer, URLs will be copy and pasted between users, and it's important to the user experience that we not store this state in the URL. I.e. it's important that the thread view URL simply be /threads/:threadId.
Edit: when someone is on a virtual thread route like /threads/:threadId, I expect that we'll store the "true route" in the history state object. I.e. the URL might look like /threads/:threadId but the history entry will have something like { realRoute: "/groups/1" } or { realRoute: "/inbox" } stored in the state object. This way we can properly handle the user choosing to reload the page. Essentially this means that, when defining our application routes, we'd like to match against not just the URL, but the history state as well.
While this pattern is supported in the browser by history.pushState, my impression is that React Router doesn't support this pattern. Is this correct? Is there a way to accomplish the above with React Router? If there isn't, I'll move this to a feature request.
Edit: ideally when defining a new route, React Router would support passing a function as the path parameter and this function would receive the current path as well as the history state and would return a boolean indicating if the current navigation matched the route (instead of just accepting a string value for the path).
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I'm trying to accomplish something with React Router that I don't think it supports (which would make this a feature request), but I'm not sure so I'm posting this in Q&A. I'm building a threaded messaging application that supports multiple groups. A single message can be sent to multiple groups. Currently, the thread view is modelled as it's own route,
/threads/:threadId
. A thread (e.g. ID1
) sent to groups1
and2
can be clicked on while browsing either group and the user will be redirected to/threads/1
for viewing the thread.We've found that rendering the group view isn't quite as snappy as we'd like and this impacts the user when they close a thread and navigate back to whatever group they were originally viewing. There are several ways we could address this (e.g. update the group view to render it's list of threads using a virtual list or simply add more performance optimizations throughout the component tree), but the way we'd like to address this for the time being is to keep the group view in the DOM (i.e. keep the group view mounted) even while the user is viewing a thread. I.e. if the user is viewing a group and clicks on a thread, from their perspective it looks like they're navigated to a new page and the URL will update to
/threads/:threadId
, but in actuality the group will stay mounted in the background and the thread view will be rendered as a dialog on top of thegroup view
. The group view will just be hidden withvisibility: hidden
. When the user closes the thread, we just close the thread dialog and show the group again withvisibility: visible
--which is very snappy (from an implementation perspective, there are some other benefits to this approach as well which I won't get into). If the user is viewing their inbox and clicks on a thread, then the URL will update to/threads/:threadId
but in actuality the inbox will stay mounted in the background and the thread will just open in a dialog on top of the inbox. If someone were to navigate directly to a thread by updating the URL in their browser and hittingEnter
, then we'll take them to their inbox and render the thread on top of it.Essentially, the thread view is not a proper route. It's a virtual route. The proper routes would be
/groups/:groupId
or/inbox
and the thread view is just a dialog rendered on top of it. But the thread view does update the URL. One response might be, why not have the URL be/groups/:groupId/thread/:threadId
or/inbox/thread/:threadId
? The answer is that our app is multiplayer, URLs will be copy and pasted between users, and it's important to the user experience that we not store this state in the URL. I.e. it's important that the thread view URL simply be/threads/:threadId
./threads/:threadId
, I expect that we'll store the "true route" in the history state object. I.e. the URL might look like/threads/:threadId
but the history entry will have something like{ realRoute: "/groups/1" }
or{ realRoute: "/inbox" }
stored in the state object. This way we can properly handle the user choosing to reload the page. Essentially this means that, when defining our application routes, we'd like to match against not just the URL, but the historystate
as well.While this pattern is supported in the browser by
history.pushState
, my impression is that React Router doesn't support this pattern. Is this correct? Is there a way to accomplish the above with React Router? If there isn't, I'll move this to a feature request.path
parameter and this function would receive the current path as well as the historystate
and would return a boolean indicating if the current navigation matched the route (instead of just accepting a string value for the path).Beta Was this translation helpful? Give feedback.
All reactions