A common pattern in most web applications is hiding unnecessary data behind tabs. However in defining these tabs you should make the data accessible in the event the user bookmarks, or shares the link. The method to share on the web is with a URL. Whether it's a absolute path, or a query param you should provide a mechanism to get back to the tab the user selected.
React Router supports this and allows for you to use normal React patterns to accomplish it.
First off we need to setup a router to render our app. We import our BrowserRouter
, render a Switch
to select between our routes.
We only really have a single route that we give a path /home
to and our component is our App
.
Don't worry too much about the Redirect
it's merely so that when navigating to /
it will redirect to our route. Essentially it's for demonstration purposes only.
https://gist.github.com/6db8852e0ab0e58e9c31a1b22a6c333f
Inside of our App.js
file we need to create some tabs. These are going to be tab routes, they'll be the components that we render based upon the URL.
https://gist.github.com/f316332b481786785375eb3b8c4a0089
These components are just normal function React components.
Now we need to setup links that will be our tab controls. We need to setup our to
links to be absolute paths so that is why we need to add the /home
to both /comments
and /contact
. The /
is taken care of by the redirect up above.
https://gist.github.com/13b8f8ccb395c142670779b9fb4b6f36
Now we need to setup our tabs. React Router allows us to setup routes anywhere, so we don't need a static route config up top.
We setup our route path
to map to our to
links. The exact
prop on the first profile route means that whenever we want to match the Profile
tab route we must be exactly at /home
. Otherwise without the exact
prop it won't render the other 2 tab routes.
https://gist.github.com/9a4e5fa0533ff715b970c96bdc699f4b
One problem with this structure is that our routes need to be absolute paths. So if we wanted to change our base route from /home
to something else we would need to change it everywhere on every link, ever Route
, etc.
So rather than statically defining them we can dynamically configure our route paths based upon the Route
that was matched from above. The match
prop that is passed in will always be whatever we have defined here <Route path="/home" component={App} />
.
https://gist.github.com/354f18ebf489c397c440b2eac2c3a4b8
Here you can see our to
on our Link
is defined dynamically. Our Route
tabs that we setup are all defined dynamically based upon our match.path
. Then we can append the additional path that we want to match for each of our tabs.
Not only does it allow us to dynamically route but it makes our Tabs reusable. Imagine if we wanted to render tab routes with the same endings but the top would match differently. This allows for you to reuse the tabs and adjust automatically for the top level.
So with this setup it doesn't matter what we define at the top level. We can change it from /home
, to something like /crazyCoolNewRoute
. Something more practical like /profile
would work to.
https://gist.github.com/7f6019259b516b854bb4bdf72442c054
Overall this just scratches the surface of some of the power that React Router provides. We've defined dynamic tabs here, but all paths can be dynamic.
https://codesandbox.io/s/github/browniefed/tmp/tree/reactRouterDynamicRoutes