회고/Techit Frontend School 10기

[멋쟁이 사자처럼 프론트엔드 스쿨] 66일차 TIL - Hook, state, 상태 끌어올리기

kelly09 2024. 8. 8. 01:01

🍰 요즘 수업 집중도는 올라가서 좋은데, 내용은 이해가 되지 않아서 슬프다. 이해했다고 생각해도 막상 실습을 시키면 손을 못 댄다. 

🍴 Hook의 등장

  • React 컴포넌트는 Container (Stateful)와 Presentational (Stateless)로 구분됨.
  • 상태를 가질 수 있는 건 클래스뿐이었고, 클래스 내부 로직은 재사용이 어려웠음.
  • 이로 인해 래퍼 헬 문제가 발생했음: 컴포넌트가 래퍼로 감싸지는 구조가 반복되어 복잡해짐.
  • 결과적으로 Huge components가 만들어져 리팩토링과 테스트가 어려워짐.

문제 해결 시도

  • 상태를 가진 로직을 재사용하려고 클래스고차 함수(H.O.C)를 사용.
  • 컴포넌트를 쪼개지 않으면 React의 장점이 사라짐.
  • 상태를 가질 수 있는 다른 방법이 필요.

Hook 등장

  • 함수 컴포넌트에서도 상태를 가질 수 있도록 Hook이 도입됨.
  • Hook은 클래스와 달리 로직 재사용을 위한 불필요한 추상 계층을 만들지 않음.
  • Hook을 사용하면 함수가 실행된 이후에도 상태를 기억할 수 있음.

Hook의 특징

  • React에서 use로 시작하는 모든 함수를 훅이라고 함.
  • React가 렌더링 중일 때만 사용할 수 있는 함수임.
  • 컴포넌트 사이의 상태를 가진 로직을 공유할 수 있음.
  • Hook은 렌더 트리를 통해 상태를 유지하거나 초기화할 수 있음.
  • 기존 클래스 방식의 복잡한 패턴을 사용하지 않음.
  • 코드 재사용캡슐화에 유리, 단방향 데이터 흐름을 유지함.

Hook 도입 후 장점

  • 로직을 컴포넌트에 직접 주입하여 클래스보다 코드가 단순해짐.
  • 관심사를 묶기가 용이해짐.
  • 트리가 클린해져 불필요한 트리가 없어짐.

결론적으로, Hook은 함수 컴포넌트에서 상태를 관리하고 로직을 재사용하기 위한 단순하고 효율적인 방법을 제공하여 React 개발을 더 용이하게 만든다.

 

🍴 Hook 사용 시 주의할 것

  • 최상위 레벨에서만 호출
  • React 함수 컴포넌트 또는 커스텀 Hook 안에서만 Hook 호출하기
  • Hook을 반복문, 조건문, 중첩 함수, try/catch/finally 블록 내부에서 호출하면 안됨(if문 뒤에 오는 방식도 안 됨)
  • 함수 이름의 첫 글자는 대문자여야 함
  • 당연히 return 이후에 호출하면 안 됨
  • useMemo, useReducer, useEffect 내에서도 Hook 호출 금지

 

🍴 state

: 컴포넌트의 기억 저장소.

  • 컴포넌트 내에서 변경 가능한 데이터를 저장하는 객체.
  • state는 화면에서 컴포넌트 인스턴스에 지역적임.
  • 동일한 컴포넌트를 두 번 렌더링하면 각 복사본은 완전히 격리된 state를 가짐.
  • props와 달리 선언한 컴포넌트에 완전히 비공개임. 부모 컴포넌트는 이를 변경할 수 없음.
  • useState 훅이 제공하는 것
    • 렌더링 간 데이터를 유지하기 위한 state 변수
    • 변수를 업데이트하고 React가 컴포넌트를 다시 렌더링하도록 유발하는 state setter 함수

 

🍴 스냅샷으로서의 state

: state 변수를 설정해도 이미 갖고 있는 state 변수가 변경되지 않고 리렌더링이 발동함.

렌더링은 그 시점의 스냅샷을 찍음.

  • 렌더링 - React가 컴포넌트(즉 함수)를 호출한다는 뜻
  • prop, 이벤트 핸들러, 로컬 변수 모두 렌더링 당시의 state를 사용해 계산됨

 

🍴 상태(state) 끌어올리기 - 컴포넌트 간 State 공유하기

: 두 컴포넌트의 state가 항상 함께 변경되기를 원할 경우, 각 컴포넌트에서 state를 제거하고 가장 가까운 공통 부모 컴포넌트로 옮긴 후 props로 전달해야 함.

  1. 자식 컴포넌트의 state 제거
  2. 하드 코딩된 값을 공통 부모로부터 전달
  3. 공통 부모에 state를 추가하고 이벤트 핸들러와 함께 전달