6. 서버 사이드 렌더링
2020-10-08
- SSR
- Server-Side Rendering (서버 측 렌더링) - 클라이언트 측 또는 유니버설 앱을 서버의 HTML로 렌더링
- CSR
- Client-Side Rendering (클라이언트 측 렌더링) - 브라우저에서 애플리케이션을 렌더링. 일반적으로 DOM을 사용
서버 렌더링은 탐색에 대한 응답으로 서버의 페이지에 대한 전체 HTML을 생성한다.
브라우저에서 응답을 받기 전에 처리되므로 클라이언트에서 데이터 가져 오기 및 템플릿 작성에 대한 추가 왕복이 발생하지 않는다.
yarn add next-urql react-is urql
- Next.js
- This integration contains convenience methods specifically for Next.js.
- react-is
- This package allows you to test arbitrary values and see if they’re a particular React element type.
withUrqlClient 고차 컴포넌트(Higher-Order Components)로 어떤 페이지이든 감싸 자동으로 서버 사이드 렌더링을 할 수 있다.
(alias) withUrqlClient(getClientConfig: NextUrqlClientConfig, options?: WithUrqlClientOptions | undefined)
utils/createClient.ts
import { dedupExchange, fetchExchange } from "urql";
import { cacheExchange } from "@urql/exchange-graphcache";
import {
LogoutMutation,
MeQuery,
MeDocument,
LoginMutation,
RegisterMutation,
} from "../generated/graphql";
import { betterUpdateQuery } from "./betterUpdateQuery";
export const createUrqlClient = (ssrExchange: any) => ({
url: "http://localhost:4000/graphql",
fetchOptions: {
credentials: "include" as const,
},
exchanges: [
dedupExchange,
cacheExchange({
updates: {
Mutation: {
logout: (_result, args, cache, info) => {
betterUpdateQuery<LogoutMutation, MeQuery>(
cache,
{ query: MeDocument },
_result,
(result, query) => ({ me: null })
);
},
login: (_result, args, cache, info) => {
betterUpdateQuery<LoginMutation, MeQuery>(
cache,
{ query: MeDocument },
_result,
(result, query) => {
if (result.login.errors) {
return query;
} else {
return {
me: result.login.user,
};
}
}
);
},
register: (_result, args, cache, info) => {
betterUpdateQuery<RegisterMutation, MeQuery>(
cache,
{ query: MeDocument },
_result,
(result, query) => {
if (result.register.errors) {
return query;
} else {
return {
me: result.register.user,
};
}
}
);
},
},
},
}),
ssrExchange,
fetchExchange,
],
});
index.tsx
const Index = () => {
const [{ data }] = usePostsQuery();
return (
<>
<NavBar></NavBar>
<div>hello world</div>
{!data ? null : data.posts.map((p) => <div key={p.id}>{p.title}</div>)}
</>
);
};
export default withUrqlClient(createUrqlClient, { ssr: true })(Index);