클라이언트 측 렌더링을 선택하기 전에 데이터 가져오기, 데이터베이스 또는 백엔드 서비스에 접근하는 등을 서버 컴포넌트에서 수행할 수 있습니다.
컴포넌트 간 데이터 공유
서버에서 데이터를 가져올 때, 서로 다른 컴포넌트 간에 데이터를 공유해야 하는 경우가 있습니다.
ex) 동일한 데이터에 의존하는 레이아웃과 페이지
React Context 혹은 데이터를 props로 전달하는 대신, fetch 혹은 cache 함수를 사용하여 동일한 데이터를 필요로 하는 컴포넌트에서 데이터를 가져올 수 있으며, 동일한 데이터에 대해 중복 요청을 만드는 것에 대해 걱정할 필요가 없습니다.
=> fetch를 확장해서 데이터를 한 번 요청하면 그 데이터를 캐시하여 다시 요청하지 않기 때문!
JavaScript 모듈은 서버와 클라이언트 컴포넌트 모듈 사이에서 공유될 수 있으므로, 서버에서만 실행될 의도로 작성한 코드가 의도치 않게 클라이언트에서 실행될 수 있습니다.
예로 아래와 같은 코드를 볼까요?
export async function getData() {
const res = await fetch('https://external-service.com/data', {
headers: {
authorization: process.env.API_KEY,
},
})
return res.json()
}
겉보기에는 getData() 함수가 서버와 클라이언트에서 모두 실행될 수 있을 것처럼 보입니다. 그러나 이 함수에는 process.env.API_KEY를 사용하는 코드가 포함되어 있어, 서버에서만 실행되어야 합니다.
Next.js에서 환경 변수는 NEXT_PUBLIC 접두사가 없는 경우 서버에서만 접근할 수 있는 개인 변수로 취급됩니다. 따라서 클라이언트에서 실행될 때 이러한 변수는 빈 문자열로 대체됩니다.
즉, getData() 함수를 클라이언트에서 가져와 실행할 수 있지만 실행하면 정상적으로 작동하지 않습니다. 변수를 공개하면 함수가 클라이언트에서 작동하지만 클라이언트에 민감한 정보를 노출하고 싶지 않을 수 있습니다.
이런 종류의 의도치 않은 클라이언트의 서버 코드 사용을 방지하기 위해, server-only 패키지를 사용하여 다른 개발자가 실수로 이러한 모듈 중 하나를 클라이언트 구성 요소에 가져올 경우 빌드 타임 오류를 제공할 수 있습니다.
npm install server-only
import 'server-only'
export async function getData() {
const res = await fetch('https://external-service.com/data', {
headers: {
authorization: process.env.API_KEY,
},
})
return res.json()
}
이제 getData() 함수를 클라이언트 컴포넌트에서 가져오려고 하면, 해당 모듈이 서버에서만 실행 가능하다는 빌드 타임 오류가 발생하게 됩니다.
위와 반대로 클라이언트 환경에서만 사용할 수 있는 client-only 패키지도 있습니다!
=> use client와 같이
서버 환경에서 사용될 수 있는 함수에는 'sever-only'
클라 환경에서 사용될 수 있는 함수에는 'client-only'
를 추가할 수 있을 것 같습니다!