기본적으로 서버 컴포넌트는 다음과 같은 동작을 한다.
서버: JSX => string으로 변환
클라: string => JSX로 변환
//사용 예시: JSON.stringify(value, stringifyJSX);
function stringifyJSX(key, value) {
if (value === Symbol.for("react.element")) {
return "$RE";
} else if (typeof value === "string" && value.startsWith("$")) {
return "$" + value;
} else {
return value;
}
}
//사용 예시: JSON.parse(value, parseJSX);
function parseJSX(key, value) {
if (value === "$RE") {
return Symbol.for("react.element");
} else if (typeof value === "string" && value.startsWith("$$")) {
return value.slice(1);
} else {
return value;
}
}
서버에서는 맨처음 ssr로 내려준다 이때 searchParams에는 jsx가 포함되어 있지 않다
그러면 string으로 변환한 JSX를 javascript에서 인식할 수 있도록 window 전역 객체에 선언해주는 부분을 script에 포함시켜준다. 그리고 클라이언트에서 받아야할 javascript 파일을 script에 작성해준다.
클라이언트에서는 최초에 window.__INITIAL_CLIENT_JSX_STRING__
이런 최초 JSX string을 가져와서 JSON parse 해준다. 그러고 hydrateRoot를 한다.
route가 바뀔 때에는 서버로부터 jsx를 가져와서 root.render해준다. 이때 같은 레이아웃은 랜더링 초기화 되지 않는데 이유는 모르겠다? 레이아웃 컴포넌트로 감싸고 page안에 있는 것만 랜더링 되는 것처럼 보여서 신기하다.
참고:
https://github.com/reactwg/server-components/discussions/5
https://codesandbox.io/p/devbox/agitated-swartz-4hs4v1?file=%2Fserver%2Frsc.js%3A149%2C19-149%2C39