728x90
작성 배경 및 문제 상황
React + MUI DataGridPro 환경에서 특정 컬럼을 pin to left(좌측 고정) 했을 때 아래와 같은 치명적인 오류가 발생:
Rendered fewer hooks than expected. This may be caused by an accidental early return statement.
같은 컬럼을 pin to right(우측 고정) 했을 때는 정상 작동하지만, 좌측 고정 시에만 오류 발생. 또한, i18next를 활용한 다국어 설정 변경 후 다이어로그를 다시 열었을 때도 같은 오류가 간헐적으로 발생함.
원인 분석
해당 오류는 React에서 Hook 호출 순서가 불일치할 때 발생함. 특히 다음과 같은 경우에 자주 발생:
renderCell
함수 내부에서useState
,useEffect
,useMemo
등을 직접 호출한 경우 (React 규칙 위반)- 조건부 분기에 따라 훅이 호출되거나 무시될 수 있는 경우
- 컬럼 구조가 조건에 따라 동적으로 바뀌어 render 시점마다 컴포넌트 구조가 달라지는 경우
DataGridPro는 column을 pin to left 할 때 내부적으로 셀을 두 번 이상 렌더링하게 되는데, 이 과정에서 hook 호출 순서가 맞지 않으면 오류가 발생함.
개선 방향
renderCell
내부에서 훅을 호출하지 않는다- Hook 로직은 모두 별도의 React 컴포넌트로 분리한다
- 컬럼 배열의 구조는 항상 일관되게 유지한다 (개수, 순서, 필드명)
이전 코드 (문제 코드)
renderCell: () => {
const [hover, setHover] = useState(false); // ❌ React 훅을 직접 호출
const isLocked = someCondition;
return (
<div>{isLocked ? <span>🔒</span> : <span>🔓</span>}</div>
);
}
개선 후 코드
renderCell: (params) => <CustomCellComponent value={params.value} />;
const CustomCellComponent = ({ value }) => {
const [hover, setHover] = useState(false);
return (
<div
onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
style={{ display: 'flex', alignItems: 'center' }}
>
{hover ? <span style={{ marginRight: '8px' }}>🔓</span> : <span style={{ marginRight: '8px' }}>🔒</span>}
<span>{value}</span>
</div>
);
};
정리 및 교훈
- React 훅은 반드시 동일한 위치에서 조건 없이 호출되어야 한다
renderCell
은 React 컴포넌트가 아니므로 훅을 절대 호출하면 안 된다- 다국어 변경, pin to left 등으로 인해 렌더링이 한 번 이상 일어날 수 있으므로 컬럼 정의는 항상 안정적으로 구성해야 한다
- Hook 기반 로직은 반드시 React 컴포넌트로 분리하여 안정성을 확보해야 한다
이와 같은 오류는 한 번 걸리면 디버깅도 어렵고, 렌더링 순서나 조건부 분기 로직까지 다 살펴야 하기 때문에 처음부터 구조를 깨끗하게 가져가는 것이 중요하다.
728x90
'버그 케이스별 대응 기록 & 컴포넌트별 동작 구조 도식화' 카테고리의 다른 글
MUI DataGridPro Drag & Drop 시 selection 상태가 undefined로 나오는 문제 해결 (0) | 2025.06.12 |
---|---|
Material UI Popper 컴포넌트 버그 케이스 대응 기록 및 동작 구조 (0) | 2025.04.22 |
댓글