Skip to main content

Zustand

General idea

to fetch data on the server-side page by adding "use server"to the top of the function body and passing the fetched data to other client-side components like the UserStoreProvider component to handle states with Zustand.

Implementation

Firstly, Create create a store to handle our states for example we create useStore :

import { create } from 'zustand'

export const useStore = create(() => ({
user: null
}))

After creating the store we need a component to set our fetched data from server-side in the Zustand store on client-side, let's call it UserStoreProvider. Then we should pass fetched data on server-side as props to the initializer component.

'use client'

import { useStore } from '@/store/useStore'

export default function UserStoreProvider({ user, children }) {
useStore.setState({
user,
// ...
})

// ...
return children
}
'use server'

export default async function Page() {
const user = await getUser()

return (
<UserStoreProvider user={user}>
// ...
</UserStoreProvider>
)
}

Also you can import your fetching fucntions from the /lib/queries . By using this architecture, we can incorporate every Next js server-side feature (like cookie) and after processing on server-side then render the app in client-side in order to store data in our state management like Zustand.

Data fetch from Zustand

Here is a structure of our store

export type UserGeneralData = {
userId: UserData['id'];
email: UserData['email'];
newEmail: string;
firstName: UserData['first_name'];
userName?: UserData['user_name'];
universityName: EducatorData['name'];
degreeProgramName?: DegreeData['name'];
universityId: UserData['university_id'];
degreeProgramId?: UserData['degree_program_id'];
lastName?: UserData['last_name'];
position?: UserData['position'];
department?: UserData['department'];
userType: CourseRole;
courseRole: CourseRole;
courseType: CourseType;
items: ItemSubset[] | ItemWithLink[];
exams: Exam[];
chapters: Chapter[];
};

Zustand stores can only be used in Client Components.

Basic example how to fetch data

export const runtime = 'edge';

export default async function Page() {
return <SelectComponent />
}
'use client';

import { useUserCourseStore } from '@/providers/UserCourseStoreProvider';
import { useUserStore } from '@/providers/UserStoreProvider';

export function SelectComponent() {
const { userId } = useUserStore((state) => state.userData);
const { userMaterial } = useUserCourseStore((state) => state.courseData);
const { items } = userMaterial;
//filter for a corresponding type
const lectures = items.filter((item) => item.type === 'lecture');

return ({
lectures.map((lecture) => (
<LectureItem
key={lecture.id}
lecture={lecture}
/>
))})
}