1. 오늘 한 것 (What I Did)
- 사용자 이벤트를 처리하는 방법
- 컴포넌트가 state를 이용하여 정보를 “기억”하는 방법
- React가 UI를 업데이트하는 두 가지 단계
- state가 변경된 후 바로 업데이트되지 않는 이유
- 여러 개의 state 업데이트를 대기열에 추가하는 방법
- state에서 객체를 업데이트하는 방법
- state에서 배열을 업데이트하는 방법
2. 새로 이해한 것 (What I Learned)
React가 리렌더링하는 동작 원리를 이해하니 State를 왜 그렇게 쓰는지 이해할 수 있었다.
1. 사용자 이벤트를 처리하는 방법
- 이벤트 핸들러는 사용자의 행동(클릭, 타이핑 등)에 반응하는 함수다.
- 함수 참조 vs 함수 호출: onClick={handleClick} (O) vs onClick={handleClick()} (X)
- 인자 전달 시: onClick={() => handleClick(id)} 형태로 화살표 함수로 감싸기
- 이벤트 객체: function handleChange(e) { console.log(e.target.value); }
2. 컴포넌트가 state를 이용하여 정보를 "기억"하는 방법
- State는 컴포넌트가 렌더링 사이에 데이터를 기억하는 방법이다. 일반 변수와 달리 state가 변경되면 컴포넌트가 다시 렌더링된다.
- 일반 변수 vs State: 일반 변수는 렌더링 시 초기화되지만, state는 값이 보존됨
- 컴포넌트 메모리: useState가 컴포넌트에게 "기억력"을 제공
- 리렌더링 트리거: state 변경 시에만 컴포넌트가 다시 렌더링됨
3. React가 UI를 업데이트하는 두 가지 단계
- React는 렌더링(Rendering)과 커밋(Committing) 두 단계로 UI를 업데이트한다.
- 렌더링: 컴포넌트 함수를 호출해서 JSX를 계산
- 커밋: 계산된 결과를 실제 DOM에 반영
- 최적화: React는 변경된 부분만 DOM에 업데이트
4. state가 변경된 후 바로 업데이트되지 않는 이유
- State는 스냅샷처럼 동작한다. setState 호출 후 즉시 변경되지 않고, 다음 렌더링에서 새 값이 반영된다.
- 스냅샷 개념: 각 렌더링에서 state 값은 고정됨
- 비동기적 업데이트: setState는 다음 렌더링을 예약하는 것
- 클로저 효과: 비동기 함수에서 클릭 당시의 state 값 유지
5. 여러 개의 state 업데이트를 대기열에 추가하는 방법
- React는 여러 state 업데이트를 큐(Queue)에 모아서 배치로 처리한다. 연속된 업데이트를 안전하게 하려면 함수형 업데이트를 사용해야 한다.
- 배치 처리: 같은 이벤트 핸들러의 여러 setState가 한 번에 처리됨
- 함수형 업데이트: setState(prev => prev + 1) 형태로 안전한 연속 업데이트
- 큐 처리: React가 내부적으로 업데이트 큐를 관리
6. state에서 객체를 업데이트하는 방법
- 객체 state는 불변성을 지켜서 업데이트해야 한다. 원본 객체를 변경하지 말고 새로운 객체를 만들어야 React가 변경을 감지할 수 있다.
- 불변성 원칙: 기존 객체를 변경하지 말고 새 객체 생성
- 스프레드 연산자: {...obj, field: newValue} 패턴
- 중첩 객체: 각 레벨마다 스프레드 연산자 필요
7. state에서 배열을 업데이트하는 방법
- 배열 state도 불변성을 지켜야 한다. 원본 배열을 변경하는 메서드(push, pop, splice 등) 대신 새 배열을 반환하는 메서드를 사용해야 한다.
- 금지 메서드: push, pop, shift, unshift, splice, sort, reverse
- 권장 패턴: [...arr, item], arr.filter(), arr.map(), [...arr].sort()
- 불변성: 원본 배열 보존하고 새 배열 생성
3. 여전히 잘 모르겠는 부분 (What I'm Still Confused About)
- Props 전달하는 부분을 잘 못 읽겠다
- 이벤트 핸들러에 'e' 전달하는 부분도 명쾌하진 않다.