Warning: Only plain objects can be passed to Client Components from Server Components이 경고는 예전에 Serve actions로 몽고 디비 데이터에 대한 GET API구현할 때 마주쳤는데 갑자기! 왜 그래야만 하는가!.. 궁금해졌습니다.
경고는 서버 컴포넌트(Server Components)와 클라이언트 컴포넌트(Client Components) 간의 데이터 전달 메커니즘과 관련이 있습니다. 이 경고와 관련된 동작 원리와 원인을 아래에 설명합니다.
서버 컴포넌트는 서버에서만 실행되며, 렌더링 결과를 직렬화된 형태(Serialized Form)로 클라이언트로 전송합니다.
이 직렬화된 데이터는 JSON 형식으로 표현되며, 클라이언트에서 복원(deserialize)되어 클라이언트 컴포넌트에서 사용됩니다.
클라이언트 컴포넌트는 브라우저에서 실행되는 JavaScript 코드로, 서버로부터 전달받은 데이터를 기반으로 UI를 그립니다.
클라이언트 컴포넌트에 데이터를 전달할 때, 서버에서 직렬화가 가능하고, 브라우저에서 복원 가능한 순수 객체(Plain Object)만 사용할 수 있습니다.
순수 객체(Plain Object)란?
Date, Map, Set, 함수 등)는 JSON으로 표현이 불가능하거나 데이터가 손실됩니다.JSON의 장점
- 데이터 전송의 간소화 :
JSON 형식은 텍스트 기반으로, 클라이언트와 서버 간에 데이터를 전송하기에 적합합니다. JSON은 텍스트 기반 포맷이므로 바이너리 데이터보다 크기가 작고, 네트워크 전송 속도가 빠릅니다.
복잡한 데이터 구조를 지원하면 전송 크기가 증가하고 성능이 저하될 수 있습니다.
직렬화된 데이터는 텍스트로 이루어져 있어 네트워크 전송 크기가 작고 속도가 빠릅니다.
클라이언트에서 쉽게 역직렬화하여 사용할 수 있습니다.- JSON의 단순성과 표준화
JSON은 모든 프로그래밍 언어에서 지원하는 표준 포맷이기 때문에 호환성과 디버깅이 용이합니다.
JSON 데이터를 읽고 쓰는 데 성능 오버헤드가 적습니다.
브라우저의 JSON.parse와 JSON.stringify는 JavaScript 엔진에 최적화되어 매우 빠르게 처리됩니다.
서버 컴포넌트에서 클라이언트 컴포넌트로 데이터를 전달하기 전에, JSON으로 변환 가능한 형태인지 확인해야 합니다.
// 서버 컴포넌트
function ServerComponent() {
const data = {
id: 1,
name: "Example",
date: new Date().toISOString(), // JSON에서 처리 가능한 형식으로 변환
};
return <ClientComponent data={data} />;
}
// 클라이언트 컴포넌트
function ClientComponent({ data }) {
return <div>{data.name}</div>;
}
Date, Map, Set 등을 클라이언트에서만 사용하도록 설계하거나, 전달하기 전에 JSON에 맞는 값으로 변환합니다.
// JSON 변환 가능하도록 처리
const date = new Date();
const plainData = {
date: date.toISOString(), // 클라이언트에서 다시 new Date()로 복원 가능
};
복잡한 객체나 함수는 서버에서! 처리하고, 클라이언트로는 결과 데이터만 전달합니다.
React가 JSON 직렬화를 강제하는 이유는 성능 최적화, 예측 가능성, 표준화, 그리고 네트워크 전송 효율성을 유지하기 위해서입니다. React의 설계 철학인 단순성과 효율성을 지키기 위한 선택입니다.
순수 객체만 전달하는 제한은:
이 경고를 해결하려면 순수 객체로 변환하거나, JSON으로 표현할 수 없는 데이터를 클라이언트에서 처리하도록 설계해야 합니다.