DEV Community

DeChamp
DeChamp

Posted on

Feedback requested on nextjs pattern for fetching data between client and server

TLDR at the bottom

Background

I'm somewhat new to NextJS. I know enough to be able to produce a working site, with understandings of most functionality.

I tell you this so you understand why I'm looking for discussion on the following pattern I'm using for my current project.

I could use some feedback to know if either I'm using a proper pattern or if I'm confused and need to go back to reading the manuals.

The Project

The project is a page of resources, just some data with a "type" to indicate the type of payload expected.

On the page, you can select a "type" as well as provide a search query.

The search query simply takes the existing data and filters it on the client side.

The "type" param is where the story begins. The type is actually passed to the query param on the API call to the backend.

The original data comes from the getServerSideProps function.

This brought me to the first issue I ran into. I was facing the issue of having the existing data being passed to my component from the getServerSideProps and then not being able to rerun the getServerSideProps function, when the "type" query param changed.

So here is what I did.

The Pattern

I realized that I would need to call the getServerSideProps function to populate the original data on the page, and then call the same data fetching on the client side.

I abstracted out the data fetching portion to it's own function and now I share it between the server and the client.

"Frontend"

   const setTypeHandler = async ({target: {value}}: any) => {
        setType(value);

        const response = await getData(document.cookie, value);

        setLocations(response.props.locations);

        router.push(`/resource${value ? `?type=${value}` : ''}`);
    }

Enter fullscreen mode Exit fullscreen mode

"Backend"

export const getServerSideProps: GetServerSideProps<any> = async (context) => {
    const {query} = context;

    const {type}: QuerySearchType = query;

    const cookie = context.req.headers.cookie;

    if (!cookie) {
        throw new Error('No user found');
    }

    return getData(cookie, type);
};
Enter fullscreen mode Exit fullscreen mode
const getData = async (cookie: string, type?: string) => { 
    // sanitize user input
    // process and return data
};
Enter fullscreen mode Exit fullscreen mode

I'm aware my code can be improved, this is only partial code for an visual. You're welcome to include things you would add/change/avoid.

Thank you and I look forward to having discussions about this.

TL;DR

getServerSideProps populates my resources page, but I need to be able to query the backend anytime the "type" select option is changed on the front end. So I use getServerSideProps for initial page load, then on the client, anytime someone changes the "type" select option, it will then call the same data fetching function that getServerSideProps uses to get the data again.

I split out the data fetching portion to be shared between getServerSideProps and my ui component. Is this the right way to do it?

Top comments (0)