Published on

4단계: 상태와 생명주기 이해

4-1. 상태(state)의 개념

컴포넌트 내부에서 변경 가능한 데이터를 의미합니다. useState 훅을 통해 선언합니다.

const [count, setCount] = useState(0);

4-2. 상태의 변경과 리렌더링

setState 함수 호출 시 해당 컴포넌트는 다시 렌더링됩니다. 변경된 state를 기반으로 UI가 자동으로 갱신됩니다.


4-3. 상태 끌어올리기

형제 컴포넌트가 공유하는 상태는 공통 부모 컴포넌트로 끌어올려야 합니다.

function Parent() {
  const [value, setValue] = useState("");
  return (
    <>
      <Input value={value} setValue={setValue} />
      <Display value={value} />
    </>
  );
}

4-4. useEffect 기초

useEffect(() => {
  console.log("마운트됨");

  return () => {
    console.log("언마운트됨");
  };
}, []);
  • 빈 배열이면 처음 1회만 실행
  • 특정 값을 넣으면 그 값이 바뀔 때마다 실행

4-5. 의존성 배열의 의미

  • [ ]: mount 시 1회 실행
  • [a]: a가 바뀔 때마다 실행
  • 생략 시: 렌더링마다 실행 (주의)

4-6. 생명주기 흐름과 대응

클래스형에서는 다음과 같은 생명주기 메서드가 있습니다:

  • componentDidMount → useEffect(() => , [])
  • componentDidUpdate → useEffect(() => , [state])
  • componentWillUnmount → useEffect cleanup return

4-7. 상태 공유 전략 비교

  • useState + props: 가장 기본
  • Context API: 중간 규모 앱
  • Redux, Zustand 등 외부 상태 관리: 대규모

4-8. 상태 성능 최적화

  • 불필요한 렌더링 방지
  • React.memo, useMemo, useCallback 등 활용
  • 상태 분리로 재렌더링 범위 최소화

요약

  • useState로 상태를 선언하고 변경 시 리렌더링 발생
  • 상태 공유는 상태 끌어올리기로 처리하며 복잡해질 경우 Context나 Redux 도입
  • useEffect는 생명주기 역할을 함수형에서 대신함
  • 성능 최적화를 위한 리렌더링 제어 기법도 필수

심화학습

Q1. useEffect에서 의존성 배열을 생략하면 어떤 문제가 발생하는가?
A1. 생략하면 렌더링마다 useEffect가 실행되기 때문에 성능 문제가 발생하거나 무한 루프에 빠질 수 있습니다.


Q2. 상태 공유가 많아질수록 컴포넌트 구조가 복잡해지는 이유는?
A2. 끌어올린 상태가 여러 계층으로 전달되면 props drilling이 발생하고 유지보수가 어려워집니다. 이럴 땐 Context나 전역 상태 관리 도구가 필요합니다.


Q3. React에서 상태 관리를 잘못했을 때 성능 이슈가 나는 대표적인 예는?
A3. 한 state 변경이 너무 넓은 범위에 영향을 주면 모든 하위 컴포넌트가 불필요하게 리렌더링됩니다. 상태는 가능한 작게 쪼개고 컴포넌트에 맞게 분리해야 합니다.