'Next.js: Passing data to nested routes
Issue:
Right now, I have a dynamic route that fetches data using getServerSideProps(). Within this page, there are multiple tabs that renders different data depending on state (which tab is selected).
I wish to transition from using multiple tabs on this page, to instead using nested routes. However, I am having difficulty obtaining the data originally fetched in these nested routes. Is there an efficient way of doing so, without having to call getServerSideProps() again?
My intended setup looks like this, where [page] calls getServerSideProps():
[page].jsx
|_tab1.jsx
|_tab2.jsx
|_tab3.jsx
My current [page].jsx, where I would like to use separate, nested pages that have access to these props (instead of rendering each tab based on state):
export default function Page(props) {
const [currentTab, setCurrentTab] = useState("home");
return (
<div>
<div id="tab1" onClick={() => setCurrentTab("home")}>
home
</div>
<div id="tab2" onClick={() => setCurrentTab("posts")}>
posts
</div>
<div id="tab3" onClick={() => setCurrentTab("info")}>
info
</div>
{currentTab === "home" ? (
<HomeTab props={props}/>
) : currentTab === "posts" ? (
<PostsTab props={props}/>
) : (
<InfoTab props={props}/>
)}
</div>
);
}
Attempts
- I've attempted using the context API to utilize data globally, which my other pages can use. However, this requires the user to visit the original dynamic route first.
- Call getServerSideProps() on each nested route. Although this works, I wish to find a better solution, since I'm fetching data on each nested route while the route they're nested under has all of this data available already.
Solution 1:[1]
You can use shallow routing in next/route or next/link
Note that, in the below example, I'm using next/link for the demonstration. Without your tab data, I'd assume you have an array of tabs in data
import { useEffect } from 'react'
import Link from 'next/link'
//the path is `/tab/:tabId`
function Tab({ data }) {
const [tabData, setTabData] = useState(data[0]) //first tab data as default for example
useEffect(() => {
setTabData(data[tabId])
}, [router.query.tabId])
return <>
<Link href="/tab/0" shallow />
<Link href="/tab/1" shallow />
<div>
{tabData}
</div>
</>
}
export async function getServerSideProps(context) {
return {
props: {
data: [], //tabs' data you fetched from the API
},
}
}
export default Tab
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nick Vu |
