
useState, useEffect, useContext, useReducer 등을 통해 상태 관리, 생명주기 관리, 컨텍스트 접근 등을 처리
Render Phase (렌더 단계, 순수 계산 단계)
컴포넌트 함수가 호출되어 JSX를 계산한다. 이때 DOM을 건드리지 않는다.
다음 훅들은 “렌더 중” 평가된다 (부수효과 금지):
useState / useReducer
state를 읽고 JSX 계산에 사용setState를 호출하면 업데이트가 스케줄링되고, 다음 렌더에서 새로운 state가 반영useState(() => init))는 최초 렌더에만 실행useMemo / useCallback
useRef
.current를 읽고/쓸 수 있으나, 변경해도 리렌더를 일으키지 않는다. DOM 연결은 커밋 이후에 유효useContext / useSyncExternalStore
useSyncExternalStore는 외부 스토어의 일관된 스냅샷을 렌더 중에 제공한다)Commit Phase (커밋 단계, DOM 반영 단계)
React가 변경된 DOM을 실제로 적용하고, 브라우저가 페인트한다(Concurrent 모드에서 스케줄링될 수 있음).
커밋 직후 실행되는 훅:
useEffect
useLayoutEffect
useInsertionEffect
Cleanup Phase (클린업 단계)
다음 중 하나의 시점에 이전 이펙트의 정리 함수가 먼저 호출된다:
해당 훅의 클린업 규칙:
useEffectuseEffect(() => { /* 구독 */ return () => { /* 구독 해제 */ } }, [deps])import React, { useState, useEffect } from "react";
function Clock() {
const [time, setTime] = useState(new Date());
// 마운트 시 타이머 등록 → 언마운트 시 정리
useEffect(() => {
const id = setInterval(() => setTime(new Date()), 1000);
return () => clearInterval(id); // cleanup
}, []);
return <h1>{time.toLocaleTimeString()}</h1>;
}

클래스형 컴포넌트의 생명주기와 상태 관리
React의 클래스 컴포넌트는 크게 생명주기 메서드(lifecycle methods)와 this.state/this.setState를 통한 상태 관리로 구성된다.
state = { count: 0 }처럼 초기값 선언this.setState({ count: this.state.count + 1 }) 호출 시 React가 새로운 렌더를 스케줄링class Clock extends React.Component {
state = { time: new Date() };
componentDidMount() {
this.timer = setInterval(() => this.setState({ time: new Date() }), 1000);
}
componentWillUnmount() {
clearInterval(this.timer);
}
render() {
return <h1>{this.state.time.toLocaleTimeString()}</h1>;
}
}
훅에서의 대체 방식
훅을 사용하면 위의 상태 관리와 생명주기 메서드가 각각 대응되는 형태로 단순화됨
useState → 함수 컴포넌트 내에서 상태 변수와 setter를 직접 반환
차이점
setState는 병합(merge) 방식useState는 치환(replace) 방식이므로, 객체 상태를 다룰 땐 명시적으로 스프레드({...state, ...update}) 해줘야 함componentDidMount + componentDidUpdate + componentWillUnmount
→ useEffect 한 곳에서 통합
useEffect(() => { ... }, [])useEffect(() => { ... }, [deps])return () => { cleanup }componentDidMount 직후 레이아웃 관련 동기 처리
useLayoutEffect로 대체componentDidCatch (에러 경계)