2019-11-20
Dynamic data fetching in Next.js
next, ssr, react, javascript, devjournal
next, ssr, react, javascript, devjournal
Image by Gerd Altmann from Pixabay
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.
Here, I am getting both posts and users from getInitialProps in index.js page.
1const Index = ({ posts, users }) => (2 <>3 <section>4 <h1>Posts</h1>5 <ul>6 {posts.map(post => (...))}7 </ul>8 </section>9 <section>10 <h1>Users</h1>11 <ul>12 {users.map(user => (...))}13 </ul>14 </section>15 </>16)17
18Index.getInitialProps = async function() {19 const postsResponse = await fetch(postsUrl)20 const posts = (await postsResponse.json()).slice(0, 5)21
22 const usersResponse = await fetch(usersUrl)23 const users = (await usersResponse.json()).slice(0, 5)24
25 return { posts, users }26}
https://codesandbox.io/s/nextjs-fetch-jsonplaceholder-posts-u4qq3?fontsize=14&hidenavigation=1&module=%2Fpages%2Findex.js&theme=dark
Credit: Refer to ups/downs on Rendering on the Web
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).
1const Users = ({ users }) => (2 <section>3 <h1>Users</h1>4 <ul>5 {users.map(user => (...))}6 </ul>7 </section>8);9
10const getUsers = url => fetch(url).then(_ => _.json());11
12const Index = ({ posts }) => {13 const [shouldFetchUsers, setShouldFetchUsers] = useState(false);14
15 const { data: users } = useSWR(16 () => (shouldFetchUsers ? usersUrl : null),17 getUsers18 );19
20 return (21 <>22 <section>23 <button onClick={() => setShouldFetchUsers(true)}>Users?</button>24 <h1>Posts</h1>25 <ul>26 {posts.map(post => (...))}27 </ul>28 </section>29 {users && <Users users={users} />}30 </>31 );32};33
34Index.getInitialProps = async function() {35 const postsResponse = await fetch(postsUrl);36 const posts = (await postsResponse.json()).slice(0, 5);37 return { posts };38};
https://codesandbox.io/s/nextjs-fetch-jsonplaceholder-posts-dynamic-users-hr34q?fontsize=14&hidenavigation=1&module=%2Fpages%2Findex.js&theme=dark
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