Rules of React는 React가 올바르게 동작하고 최적화하기 위해 코드가 지켜야 하는 규칙으로, 공식 문서가 세 가지로 정리한다. 핵심은 렌더가 순수한 계산이어야 한다는 것이다.
- 컴포넌트와 훅은 순수해야 한다. 같은 입력(props·state·context)이면 같은 JSX(JavaScript XML)를 낸다. 부수 효과는 렌더 밖(이벤트 핸들러, Effect)에서 실행한다. props·state, 훅의 인자와 반환값, JSX에 넘긴 값은 불변 스냅샷으로 다루고 고치지 않는다
- 컴포넌트와 훅은 React가 호출한다.
Profile()처럼 직접 부르지 말고 JSX로 쓴다. 훅을 값처럼 넘기지 않는다. React가 호출해야 트리 위치에 state를 묶고 재조정에 참여시킬 수 있다 - 훅은 최상위(Top Level)에서만 호출한다. 조건문·반복문·중첩 함수 안에서 부르지 않는다. React는 호출 순서로 각 훅의 state를 찾기 때문에, 하나를 건너뛰면 뒤의 훅이 한 칸씩 밀린다. 훅은 컴포넌트나
use로 시작하는 커스텀 훅 안에서만 부른다. use()만은 조건문·반복문 안에서도 부를 수 있다
왜 이렇게 엄격한가
React는 같은 컴포넌트를 여러 번 부를 수 있다(엄격 모드(Strict Mode)는 개발 중 일부러 두 번 렌더한다). 동시성 모드에서는 렌더를 멈췄다 다시 하거나 통째로 버리기도 하고(동시성 렌더링), 다 그린 트리를 커밋 때 바꿔 끼운다(Fiber 아키텍처). 렌더가 순수해야 몇 번을 실행하든 결과가 같다. 렌더 중 Math.random()·Date.now()는 하이드레이션 불일치(Hydration Mismatch)와 잘못된 메모이제이션을 만든다.
- 같은 입력에 같은 결과라는 성질은 서버 쪽 멱등성(Idempotency)과 닮았다
- React Compiler는 이 규칙을 전제로 최적화하고, 어기면 그 컴포넌트를 건너뛴다
eslint-plugin-react-hooks가 대부분을 자동으로 잡아 준다- 부수 효과의 정의는 부수 효과와 Effect