[ 살펴보기 ] Jotai - SSR & NextJS

[ 살펴보기 ] Jotai - SSR & NextJS

·

2 min read

Server side에서 처리된 data를 특정 atom의 초기값으로 사용할 수 있도록 Jotai에서 useHydrateAtoms이라는 util 함수를 제공한다.

아래 예제를 통해 어떻게 NextJS에서 Server에서 fetch한 데이터를 useHydrateAtoms를 통해 특정 atom의 초기값을 설정하는지 살펴보자

NextJS - Page route

import { useHydrateAtoms } from "jotai/utils";

export const getStaticProps = async () => {
  const userlist = await apiGetDataList();
  return { props: { userlist } };
};

const UserSSR = ({ userlist }: User[]) => {
  useHydrateAtoms([[userSSRAtom, userlist]]);
  return (
    <PageContainer pageMetaTitle="user - static">
      <h3>User ( SSR )</h3>
      <UserSSRChild />
    </PageContainer>
  );
};

NextJS page route에선 server에서 data fetch 처리를 위해 getStaticProps 함수와 getServerSideProps 함수를 사용한다. 이 두 함수 안에서 발생하는 data fetch는 server side에서 처리되며 결과 값을 특정 page의 props으로 전달할 수 있다.

위의 예제에서는 userList 데이터 fetch를 server에서 처리하고 페이지 에서는 해당 데이터를 전달받아 userSSRAtom라는 atom의 초기값으로 설정하여 UserSSRChild에서 초기값이 설정된 userSSRAtom을 바로 사용할 수 있다.

한 가지 주의할 점은 NextJS에서 Jotai를 사용할 경우 다음과 같이 application root level에 store를 명시적으로 선언하여 SSR 환경에서 store의 lifetime을 제한하는 것이 좋다.

import { Provider } from 'jotai'

export default function App({ Component, pageProps }: AppProps) {
  return (
   <ErrorBoundary fallback={<div>Error Boundary</div>}>
    <Provider>
      <Component {...pageProps} />
    </Provider>
  </ErrorBoundary>
  )
}

NextJS - App Route

App route에선 SSR 처리를 위해 getStaticProps나 getServerSideProps와 같은 별도 함수를 제공하지 않고 component 상단에 "use client"를 별도로 설정하지 않으면 모두 server에서 실행되는 server component로 가정한다

그렇기에 다음 예제와 같이 상단의 server component에서 fetch한 데이터를 client component의 prop으로 전달하여 useHydrateAtoms util을 통해 server에서 fetch한 값을 특정 atom의 초기 값으로 설정할 수 있다.

 const TestJotaiPage = async () => {
  const userlist = await apiGetDataList();

  return (
    <div>
      <h3>TestJotai</h3>
      <TestJotaiChild userlist={userlist} />
    </div>
  );
};

export default TestJotaiPage;
"use client";

type Props = {
  userlist: UserList;
};

const TestJotaiChild = ({ userlist }: Props) => {
  useHydrateAtoms([[userSSRAtom, userlist]]);
  return (
    <div>
      <h3>TestJotaiChild</h3>
      <TestJotaiGrandChild />
    </div>
  );
};

export default TestJotaiChild;

위와 같이 userSSRAtom의 초기값을 설정하면 다른 component에서 초기 값이 설정된 userSSRAtom을 바로 사용할 수 있다.