From aa542a4051d47aa105d138a7e3a254a06f1be352 Mon Sep 17 00:00:00 2001 From: promer94 Date: Mon, 11 Mar 2024 07:23:09 +0800 Subject: [PATCH] examples: add RSC streaming pre-render with promise fallback example (#2905) examples: add RSC streaming prerender with promise fallback example --- examples/suspense/app/favicon.ico | Bin 0 -> 39535 bytes examples/suspense/app/layout.jsx | 9 +++++ .../suspense/app/rsc/[user]/[repo]/error.jsx | 4 ++ .../app/rsc/[user]/[repo]/loading.jsx | 3 ++ .../suspense/app/rsc/[user]/[repo]/page.jsx | 23 ++++++++++++ .../suspense/app/rsc/[user]/[repo]/repo.jsx | 21 +++++++++++ examples/suspense/app/rsc/loading.jsx | 3 ++ examples/suspense/app/rsc/page.jsx | 8 ++++ examples/suspense/app/rsc/repos.jsx | 24 ++++++++++++ examples/suspense/next-env.d.ts | 6 +++ examples/suspense/pages/[user]/[repo].js | 35 ++++++++---------- examples/suspense/pages/api/data.js | 28 +++++++------- examples/suspense/pages/index.js | 26 +++++++------ 13 files changed, 145 insertions(+), 45 deletions(-) create mode 100644 examples/suspense/app/favicon.ico create mode 100644 examples/suspense/app/layout.jsx create mode 100644 examples/suspense/app/rsc/[user]/[repo]/error.jsx create mode 100644 examples/suspense/app/rsc/[user]/[repo]/loading.jsx create mode 100644 examples/suspense/app/rsc/[user]/[repo]/page.jsx create mode 100644 examples/suspense/app/rsc/[user]/[repo]/repo.jsx create mode 100644 examples/suspense/app/rsc/loading.jsx create mode 100644 examples/suspense/app/rsc/page.jsx create mode 100644 examples/suspense/app/rsc/repos.jsx create mode 100644 examples/suspense/next-env.d.ts diff --git a/examples/suspense/app/favicon.ico b/examples/suspense/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..4570eb8d9269ad58b17fecbec6d630cded56f507 GIT binary patch literal 39535 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 literal 0 HcmV?d00001 diff --git a/examples/suspense/app/layout.jsx b/examples/suspense/app/layout.jsx new file mode 100644 index 000000000..659980d8d --- /dev/null +++ b/examples/suspense/app/layout.jsx @@ -0,0 +1,9 @@ +export default function RootLayout({ + children +}) { + return ( + + {children} + + ) +} diff --git a/examples/suspense/app/rsc/[user]/[repo]/error.jsx b/examples/suspense/app/rsc/[user]/[repo]/error.jsx new file mode 100644 index 000000000..d26979655 --- /dev/null +++ b/examples/suspense/app/rsc/[user]/[repo]/error.jsx @@ -0,0 +1,4 @@ +'use client' +export default function ErrorPage() { + return
Error happen
; +} \ No newline at end of file diff --git a/examples/suspense/app/rsc/[user]/[repo]/loading.jsx b/examples/suspense/app/rsc/[user]/[repo]/loading.jsx new file mode 100644 index 000000000..ac709eb97 --- /dev/null +++ b/examples/suspense/app/rsc/[user]/[repo]/loading.jsx @@ -0,0 +1,3 @@ +export default function Loading() { + return
Loading...
; +} \ No newline at end of file diff --git a/examples/suspense/app/rsc/[user]/[repo]/page.jsx b/examples/suspense/app/rsc/[user]/[repo]/page.jsx new file mode 100644 index 000000000..762190dcb --- /dev/null +++ b/examples/suspense/app/rsc/[user]/[repo]/page.jsx @@ -0,0 +1,23 @@ +import Repo from './repo' +import fetcher from '../../../../libs/fetch' +import Link from 'next/link' +import { Suspense } from 'react' +const Page = ({ params }) => { + const { user, repo } = params + const id = `${user}/${repo}` + const serverData = fetcher('http://localhost:3000/api/data?id=' + id) + return ( +
+
Repo: {id}
+ Loading stats
}> + + +
+
+ Back + + ) +} + + +export default Page \ No newline at end of file diff --git a/examples/suspense/app/rsc/[user]/[repo]/repo.jsx b/examples/suspense/app/rsc/[user]/[repo]/repo.jsx new file mode 100644 index 000000000..a87c8df0f --- /dev/null +++ b/examples/suspense/app/rsc/[user]/[repo]/repo.jsx @@ -0,0 +1,21 @@ +'use client' +import fetcher from '../../../../libs/fetch' +import useSWR from 'swr' + +const Repo = ({ id, serverData }) => { + const { data } = useSWR('/api/data?id=' + id, fetcher, { suspense: true, fallbackData: serverData }) + return ( + <> + {data ? ( +
+

forks: {data.forks_count}

+

stars: {data.stargazers_count}

+

watchers: {data.watchers}

+
+ ) : null} + + + ) +} + +export default Repo \ No newline at end of file diff --git a/examples/suspense/app/rsc/loading.jsx b/examples/suspense/app/rsc/loading.jsx new file mode 100644 index 000000000..ac709eb97 --- /dev/null +++ b/examples/suspense/app/rsc/loading.jsx @@ -0,0 +1,3 @@ +export default function Loading() { + return
Loading...
; +} \ No newline at end of file diff --git a/examples/suspense/app/rsc/page.jsx b/examples/suspense/app/rsc/page.jsx new file mode 100644 index 000000000..a6df667a6 --- /dev/null +++ b/examples/suspense/app/rsc/page.jsx @@ -0,0 +1,8 @@ +import fetcher from '../../libs/fetch' +import Repos from './repos' +const Page = () => { + const serverData = fetcher('http://localhost:3000/api/data') + return +} + +export default Page diff --git a/examples/suspense/app/rsc/repos.jsx b/examples/suspense/app/rsc/repos.jsx new file mode 100644 index 000000000..557641844 --- /dev/null +++ b/examples/suspense/app/rsc/repos.jsx @@ -0,0 +1,24 @@ +'use client' +import useSWR from 'swr' +import fetcher from '../../libs/fetch' +import Link from 'next/link' + +const Repos = ({ serverData }) => { + const { data } = useSWR('/api/data', fetcher, { + suspense: true, + fallbackData: serverData + }) + return ( + <> + {data.map(project => ( +

+ + {project} + +

+ ))} + + ) +} + +export default Repos \ No newline at end of file diff --git a/examples/suspense/next-env.d.ts b/examples/suspense/next-env.d.ts new file mode 100644 index 000000000..fd36f9494 --- /dev/null +++ b/examples/suspense/next-env.d.ts @@ -0,0 +1,6 @@ +/// +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/examples/suspense/pages/[user]/[repo].js b/examples/suspense/pages/[user]/[repo].js index e7fef9f7f..178762d4d 100644 --- a/examples/suspense/pages/[user]/[repo].js +++ b/examples/suspense/pages/[user]/[repo].js @@ -2,13 +2,10 @@ import { Suspense } from 'react' import Link from 'next/link' import fetcher from '../../libs/fetch' import ErrorHandling from '../../components/error-handling' - import useSWR from 'swr' -const isServer = typeof window === 'undefined' - -const Detail = ({ id }) => { - const { data } = useSWR('/api/data?id=' + id, fetcher, { suspense: true }) +const Detail = ({ id, serverData }) => { + const { data } = useSWR('/api/data?id=' + id, fetcher, { suspense: true, fallbackData: serverData }) return ( <> @@ -23,25 +20,25 @@ const Detail = ({ id }) => { ) } -export default function Repo() { - const id = - typeof window !== 'undefined' ? window.location.pathname.slice(1) : '' - +export default function Repo({ id, serverData }) { return (

{id}

- {!isServer ? ( - loading...
}> - oooops!}> - - - - ) : null} + loading...}> + oooops!}> + + +

- - Back - + Back ) } + +export const getServerSideProps = async ({ params }) => { + const { user, repo } = params + const id = `${user}/${repo}` + const data = await fetcher('http://localhost:3000/api/data?id=' + id).catch(() => {}) + return { props: { serverData: data, id } } +} \ No newline at end of file diff --git a/examples/suspense/pages/api/data.js b/examples/suspense/pages/api/data.js index 5bc3ab502..c0ef97162 100644 --- a/examples/suspense/pages/api/data.js +++ b/examples/suspense/pages/api/data.js @@ -12,21 +12,19 @@ export default function api(req, res) { setTimeout(() => { res.json({ msg: 'not found' }) }) - - return + } else { + // a slow endpoint for getting repo data + fetch(`https://api.github.com/repos/${req.query.id}`) + .then(res => res.json()) + .then(data => { + setTimeout(() => { + res.json(data) + }, 2000) + }) } - // a slow endpoint for getting repo data - fetch(`https://api.github.com/repos/${req.query.id}`) - .then(res => res.json()) - .then(data => { - setTimeout(() => { - res.json(data) - }, 2000) - }) - - return + } else { + setTimeout(() => { + res.json(projects) + }, 2000) } - setTimeout(() => { - res.json(projects) - }, 2000) } diff --git a/examples/suspense/pages/index.js b/examples/suspense/pages/index.js index e94b75451..2671e9974 100644 --- a/examples/suspense/pages/index.js +++ b/examples/suspense/pages/index.js @@ -1,13 +1,14 @@ import { Suspense } from 'react' import Link from 'next/link' -import fetcher from '../libs/fetch'; +import fetcher from '../libs/fetch' import useSWR from 'swr' -const isServer = typeof window === 'undefined' - -const Repos = () => { - const { data } = useSWR('/api/data', fetcher, { suspense: true }) +const Repos = ({ serverData }) => { + const { data } = useSWR('/api/data', fetcher, { + suspense: true, + fallbackData: serverData + }) return ( <> @@ -22,15 +23,18 @@ const Repos = () => { ) } -export default function Index() { +export default function Index({ serverData }) { return (

Trending Projects

- {!isServer ? ( - loading...
}> - - - ) : null} + loading...}> + + ) } + +export const getServerSideProps = async () => { + const data = await fetcher('http://localhost:3000/api/data') + return { props: { serverData: data } } +}