react-router-native
react-router-native copied to clipboard
Same routes shared across multiple tabs.
I have a use case where there are many routes that are shared across multiple tab stacks.
Example:
<TabsRoute>
<StackRoute>
<IndexRoute path="/friends">
<Route path="/user/:userId">
<Route path="/user/:userId/followers">
</StackRoute>
<StackRoute>
<IndexRoute path="/me">
<Route path="/user/:userId">
<Route path="/user/:userId/followers">
</StackRoute>
</TabsRoute>
/friends shows list of friends.
/me shows my account.
/user/:userId shows a profile of a user.
/user/:userId/followers shows a list of followers for a user.
Note that user can navigate to user profile and user followers from both friends and me tab.
They also share the same url pattern.
Since all routes are pretty much somehow connected to each other (think of Facebook app), almost all routes can be accessed from any tab stacks.
Desired behavior would be not to jump around between tabs, but stay in the current one if there is a matching route under the current tab, then push the matching route to the current tab stack. Also, it would be nice if it can be done without copying common routes to each tab stack.
React Router matches routes in the order they are defined. See also, reactjs/react-router#1923. Hence, the jumps between tabs. So you will need to make sure "identical" paths are relative to their respective <StackRoute> or <TabRoute>.
I think the best way to approach it will be the following:
const userRoutes = (
/* relative paths */
<Route path="user/:userId">
<Route path="user/:userId/followers">
);
const routes = (
<TabsRoute path="/">
<StackRoute path="/friends">
<Route path="list">
{userRoutes}
</StackRoute>
<StackRoute path="/profile">
<Route path="me">
{userRoutes}
</StackRoute>
</TabsRoute>
);
However, there is a bug, #17, that prevents this from working as expected. The fix should be live in a ~~week or so~~ few weeks.
🍺
With proposed solution, how can I hide tab bar when on userRoutes? Trying to build something similar like FB messenger (Home -> conversation, People -> conversation)
@arthurpark You can refer to https://github.com/facebook/react-native/issues/8350 for how to control overlays from the scene. I think the best way is to use either redux or some kind of event system as suggested on the thread. @jmurzy What do you think about writing a new url matcher that first matches routes under the current route subtree, then climb up the tree if not found, and so on, for each level? The new matcher will always try to match the route that is closest to the current route, and there can be multiple routes sharing the same url pattern. Do you see any potential problems with this approach?
@arthurpark Take a look at the example app. The only difference is that instead of rendering the tabs in the Master component, you'd have to put them in each of your route components that render the individual tabs. So when the transition happens, tabs will just simply hide away as with the rest of your tab component.
@joonhocho I'm still working on this. Recent refactoring of the internal API was to pave the way for more flexibility in how routes are matched. I need to cover all the cases and avoid as much of the magic as possible. Honestly, this is the reason why I'm still tagging the releases with alpha.
🍺