Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How Do I Handle Typesafe Modular Data Fetching in Next.js? #69

Open
VienDinhCom opened this issue Apr 18, 2023 · 0 comments
Open

How Do I Handle Typesafe Modular Data Fetching in Next.js? #69

VienDinhCom opened this issue Apr 18, 2023 · 0 comments

Comments

@VienDinhCom
Copy link
Owner

VienDinhCom commented Apr 18, 2023

Challenge

During the development cycle, we constantly add new features, fix bugs and refactor the code to improve readability and performance. And with many developers working on one project, moving fast and breaking nothing could be a challenge. In this article, I am going to share with you how I handle data fetching safely, and modularly in Next.js projects to solve this challenge.

Solution

When we do data fetching in Next.js, we tend to put all our code inside getServerSideProps or getStaticProps, and then we pass the data down to the component tree. However, this approach makes it hard to reuse our code on different pages.

Instead, I suggest we should split our pages into modular sections. Each section file has its UI component and its data fetching function. So we can reuse a section on many pages without rewriting data fetching code and reimplementing data types.

To simplify the process, I have created an npm package called @maxvien/next. This package includes some functions and type utilities that could help implement my approach cleaner.

Define a Modular Section

A modular section has two things. One is the Component for building UI. One is the Data Fetching Function for the Component.

To quickly create the props type for the Component, we use the DataProps utility. The DataProps utility will take the return type of the Data Fetching Function and assign it to the data prop as you can see below.

import { DataProps } from '@maxvien/next';

// Data Fetching Function
export async function fetchExampleSection(id: string) {
  const person = await getPersonFromApi(id);

  return person as { name: string; age: number };
}

// Component
export function ExampleSection(props: DataProps<typeof fetchExampleSection>) {
  return (
    <section>
      <h1>Person</h1>
      <p>Name: {props.data.name}</p>
      <p>Age: {props.data.age}</p>
    </section>
  );
}

Thanks to the benefit of tree shacking, Webpack will remove the fetchExampleSection function from the client bundle, so you don't need to be worried about including your server code on browsers. Because we don't use the function directly in the Component.

If Webpack fires errors when you use Node.js modules like fs, you should put some lines of code into package.json like below to tell Webpack to exclude modules from the client bundle.

"browser": {
  "fs": false
}

Use a Modular Section

For data fetching, instead of defining a normal function, we use utility functions like fetchServerSideProps, fetchStaticProps, and fetchStaticPaths from the @maxvien/next package. These functions will help the PageProps utility to take the return type of the data fetching functions and assign it to the page props as you can see below.

import { fetchStaticProps, PageProps } from '@maxvien/next';
import { ExampleSection, fetchExampleSection } from '../sections/ExampleSection';

export const getStaticProps = fetchStaticProps(async ({ params }) => {
  const id = params?.id as string;

  return {
    props: {
      data: {
        exampleSection: await fetchExampleSection(id),
      },
    },
  };
});

export default function Page(props: PageProps<typeof getStaticProps>) {
  return <ExampleSection data={props.data.exampleSection}></ExampleSection>;
}

You can find real implementations here: https://github.com/maxvien/next-shopify-storefront/tree/v3/src/pages/products

Conclusion

That is how I handle typesafe modular data fetching in Next.js. I hope my little solution can help you add new features, fix bugs and refactor your code more safely throughout the development cycle. Thank you for reading!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant