← 전체 글로 돌아가기

Next.js

React에서 조건부 렌더링이 제대로 작동하지 않을 때

로컬에서는 정상이던 조건부 렌더링이 실제 배포 환경에서 이상하게 작동할 때 어디를 봐야 할까.

문제를 제대로 파악해야 수정이 빠르다

조건부 렌더링 버그는 원인이 정말 다양한데, 처음 사람들이 하는 실수는 한 가지 가능성만 고집하는 것이다. 나도 처음엔 렌더링 함수의 조건문을 의심했는데, 실제론 데이터를 받아오는 쪽의 타이밍 문제였다.

버그를 빨리 찾으려면 현상부터 정확히 관찰하는 게 중요하다. "화면에 안 보여"라고 하지 말고, 어떤 조건에서 안 보이는지, 새로고침하면 나타나는지, 특정 브라우저에서만 그런지 구체적으로 적어두자.

확인해야 할 순서

먼저 로그를 본다. 브라우저의 개발자 도구 콘솔에서 에러가 있는지, 그리고 컴포넌트가 어떤 props나 state를 받고 있는지 확인한다.

// 즉시 조건문 주변에 console.log를 넣어본다
console.log('isVisible:', isVisible, 'user:', user);
if (isVisible && user) {
  return <Component />;
}
return null;

다음으로 실제 HTML을 본다. 개발자 도구의 Elements 탭에서 해당 요소가 DOM에 있는지 없는지 확인한다. 있으면 CSS로 숨겨진 걸 수도 있고, 없으면 렌더링이 제대로 안 된 거다.

로컬과 배포 환경의 차이 확인

빌드 후 실제로 어떤 값이 바뀌는지 보자. npm run build를 실행하고 프로덕션 빌드를 로컬에서 직접 띄워본다.

npm run build
npm run start  # Next.js의 경우
# 또는
npx http-server ./dist  # 일반 React 프로젝트의 경우

그 다음 네트워크 탭에서 API 요청을 본다. 로컬 개발 환경과 프로덕션 환경에서 서버 응답이 다를 수 있다. 예를 들어 권한이 없는 경우 데이터가 안 오거나, 빈 배열이 올 수도 있다.

겹치기 쉬운 함정들

Async 데이터와 초기값: 컴포넌트가 로드되자마자 isLoading이 true인데 조건문이 if (!isLoading && data)라면, 처음 렌더링 때 아무것도 안 보인다. useEffect에서 데이터를 받아올 때까지 기다려야 한다.

State가 업데이트되지 않음: 부모에서 props로 받은 값을 자식 컴포넌트의 state 초기값으로 썼는데, 부모가 업데이트되어도 자식의 state는 그대로인 경우가 있다.

// 위험: props가 바뀌어도 state는 바뀌지 않음
const [value, setValue] = useState(props.initialValue);

// 올바른: useEffect로 동기화
useEffect(() => {
  setValue(props.value);
}, [props.value]);

조건이 너무 까다로움: if (user && user.id && user.permissions && user.permissions.includes('admin'))처럼 중첩된 조건은 하나라도 false면 전체가 렌더링되지 않는다. 각 단계를 따로 로깅해보자.