Dynamic data fetching in Next.js
After going thru the wonderful Next.js tutorial, I decided to write a simple data fetching site from scratch.
It was tougher than I expected.
TIL that you can fetch data from getInitialProps
to return a shell, and also let the rest of the page "dynamic" using fetch
.
Server-side data fetch with "getInitialProps"
Here, I am getting both posts
and users
from getInitialProps
in index.js
page.
const Index = ({ posts, users }) => (
<>
<section>
<h1>Posts</h1>
<ul>
{posts.map(post => (...))}
</ul>
</section>
<section>
<h1>Users</h1>
<ul>
{users.map(user => (...))}
</ul>
</section>
</>
)
Index.getInitialProps = async function() {
const postsResponse = await fetch(postsUrl)
const posts = (await postsResponse.json()).slice(0, 5)
const usersResponse = await fetch(usersUrl)
const users = (await usersResponse.json()).slice(0, 5)
return { posts, users }
}
Credit: Refer to ups/downs on Rendering on the Web
Client-side data fetch (with "SWR")
Second experiment was to fetch users dynamically on button click.
I was skeptical that it'd work as HTML is generated on the server.
But I was able to get users data on the client-side no problem.
You can see that I am fetching only posts via getInitialProps
but users data is fetched using useSWR(, which is a convinience method to fetch remote data from Zeit to w/o useEffect
boilerplate code).
const Users = ({ users }) => (
<section>
<h1>Users</h1>
<ul>
{users.map(user => (...))}
</ul>
</section>
);
const getUsers = url => fetch(url).then(_ => _.json());
const Index = ({ posts }) => {
const [shouldFetchUsers, setShouldFetchUsers] = useState(false);
const { data: users } = useSWR(
() => (shouldFetchUsers ? usersUrl : null),
getUsers
);
return (
<>
<section>
<button onClick={() => setShouldFetchUsers(true)}>Users?</button>
<h1>Posts</h1>
<ul>
{posts.map(post => (...))}
</ul>
</section>
{users && <Users users={users} />}
</>
);
};
Index.getInitialProps = async function() {
const postsResponse = await fetch(postsUrl);
const posts = (await postsResponse.json()).slice(0, 5);
return { posts };
};
Unrelated but just a thought.
I just ran across "App Shell model", for which Next.js can be used to provdie the "shell" and do dynamic data fetching after the load.
https://developers.google.com/web/fundamentals/architecture/app-shell
Image by Gerd Altmann from Pixabay
Webmentions
Loading counts...