React 스터디 - React 학습하기 (1)

오다혜·2024년 10월 27일
0

문서를 읽게 된 동기

회사에서 Vue2 인 프로젝트를 React 로 마이그레이션 하는 작업을 진행중입니다. 코드의 퀄리티를 높이고, 팀원 분들의 PR을 더 수준높게 봐드리고 싶어서 React 공식문서를 읽게 되었습니다. 기존 vue 문법과 어떤 점이 다른 지를 비교하면서 문서를 보려고 합니다.

React 문서 소개

https://ko.react.dev/

react는 한글판 문서가 따로 존재합니다. 문서가 자세해서 새로 배우시는 분들도 학습하기 좋습니다.

학습하기 탭에서는 기본적인 개념부터 심화과정까지 react 를 다루는 방법을 소개하고 있습니다. 예제가 자세하고, 각 섹션 하단에 직접해볼 수 있는 챌린지가 있어 직접 코드를 짜보면서 학습할 수 있어 좋았습니다.

빠르게 시작하기

React로 사고하기

  • state는 앱이 기억해야 하는, 변경할 수 있는 데이터의 최소 집합이다.
  • state를 구조화하는 데 가장 중요한 원칙은 중복배제원칙(Don’t Repeat Yourself) ⇒ DB 의 정규화와 유사
  • 애플리케이션이 필요로 하는 가장 최소한의 state를 파악하고 나머지 모든 것들은 필요에 따라 실시간으로 계산

state 가 아닌 것

  • 시간이 지나도 변하지 않는 것: 상수
  • 부모로부터 props를 통해 전달되는 것: 외부에 종속된 데이터로, 내부의 상태가 아님
  • 컴포넌트 안의 다른 state나 props를 가지고 계산 가능한 것: 최소한의 state 가 아님

state 의 위치

  1. 해당 state를 기반으로 렌더링하는 모든 컴포넌트를 찾기
  2. 그들의 가장 가까운 공통되는 부모 컴포넌트를 찾기 - 계층에서 모두를 포괄하는 상위 컴포넌트
  3. state가 어디에 위치 돼야 하는지 결정
    1. 대개, 공통 부모에 state를 그냥 두기
    2. 혹은, 공통 부모 상위의 컴포넌트에 두기
    3. state를 소유할 적절한 컴포넌트를 찾지 못하였다면, state를 소유하는 컴포넌트를 하나 만들어서 상위 계층에 추가하기

⇒ state 의 위치를 파악할 때 위의 조건을 상기할 것!

UI 표현하기

컴포넌트 import 및 export 하기

  • React에서는 './Gallery.js' 또는 './Gallery' 둘 다 사용할 수 있지만 전자의 경우가 native ES Modules 사용 방법에 더 가깝다.

컴포넌트에 props 전달하기

JSX spread 문법으로 props 전달하기

  • props를 직접 사용하지 않기 때문에 보다 간결한 “spread” 문법을 사용하는 것이 합리적일 수 있다.
  • spread 문법은 제한적으로 사용하세요. 다른 모든 컴포넌트에 이 구문을 사용한다면 문제가 있는 것이다.
    • 자식을 JSX로 전달해야 해서 spread 를 여러 번 사용하지 않게 방지할 수 있음

시간에 따라 props가 변하는 방식

  • props는 컴퓨터 과학에서 “변경할 수 없다”라는 의미의 불변성을 가지고 있다.
  • 컴포넌트가 props를 변경해야 하는 경우(예: 사용자의 상호작용이나 새로운 데이터에 대한 응답): 부모 컴포넌트에 다른 props, 즉 새로운 객체를 전달하도록 “요청”해야 한다
    • 이전의 props는 버려지고, 기존 props가 차지했던 메모리가 회수된다.
  • Props는 변경할 수 없다. 상호작용이 필요한 경우 state를 설정해야 한다.

⇒ props 는 렌더링 시마다 불변의 값을 가진다. 렌더링 시에 props 를 변경하는 행위를 해서는 안 된다. ex) props.value = props.value + 1

조건부 렌더링

조건부로 null을 사용하여 아무것도 반환하지 않기

if (isPacked) {
  return null;
}
return <li className="item">{name}</li>;
  • 실제로 컴포넌트에서 null을 반환하는 것은 개발자가 렌더링하려고 할 때 놀랄 수 있기 때문에 흔한 경우는 아니다.

⇒ null 을 반환하는 대신 상위에서 조건절을 통해서 컴포넌트 렌더링을 막는 방식을 사용하자.

if (isPacked) {
  return <li className="item">{name}</li>;
}
return <li className="item">{name}</li>;

상호작용성 더하기

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

hook 규칙

  • 훅(use로 시작하는 함수들)은 컴포넌트의 최상위 수준 또는 커스텀 훅에서만 호출할 수 있다.
    • 조건문, 반복문 또는 기타 중첩 함수 내부에서는 훅을 호출할 수 없습니다.

연관된 state 하나로 합치기

  • 서로 연관이 없는 경우 여러 개의 state 변수를 가지는 것이 좋다.
  • 하지만 두 state 변수를 자주 함께 변경하는 경우에는 두 변수를 하나로 합치는 것이 더 좋을 수 있다.

State 업데이트 큐

batching

  • React는 state 업데이트를 하기 전에 이벤트 핸들러의 모든 코드가 실행될 때까지 기다린다.
    • React 앱을 훨씬 빠르게 실행할 수 있게 해준다.
    • 일부 변수만 업데이트된 “반쯤 완성된” 혼란스러운 렌더링을 처리하지 않아도 된다.
  • React는 클릭과 같은 여러 의도적인 이벤트에 대해 batch를 수행하지 않으며, 각 클릭은 개별적으로 처리된다.
  • React는 안전한 경우에만 batch를 수행한다.

⇒ 안전한 경우 라는 것이 무엇인가..

객체 state 업데이트하기

state 값은 읽기 전용처럼 다루어야 한다.

여러 필드에 단일 이벤트 핸들러 사용하기

  function handleChange(e) {
    setPerson({
      ...person,
      [e.target.name]: e.target.value
    });
  }

immer

  • Immer가 제공하는 draft: Proxy
  • 내부적으로 draft의 어느 부분이 변경되었는지 알아내어, 변경사항을 포함한 완전히 새로운 객체를 생성

배열 State 업데이트하기

배열 내부의 객체 업데이트하기

  • 중첩된 state를 업데이트할 때, 업데이트하려는 지점부터 최상위 레벨까지의 복사본을 만들어야 한다.
  • 일반적으로 깊은 레벨까지의 state를 업데이트할 필요는 없다. state 객체가 매우 깊다면 평탄하게 만드는 것을 고려해야 한다.
  • state 구조를 변경하고 싶지 않다면, Immer 사용할 수 있다.

스터디 1차 후기

느낀 점

문서에 써있음에도 읽어보지 않아 몰랐던 내용이 많았습니다. 기본적인 컨벤션부터 내부 동작원리까지 문서에 적혀있는 부분이 많아 신기했습니다. 공식 문서에서 immer 를 적극(?) 활용하라고 권유하는 부분이나, useEffect 를 사용하지 않아도 되는 여러 사례들이 제일 인상적이었습니다.

궁금한 점

문서를 읽으면서 조금 더 깊게 고민해보고자 하는 내용들입니다. 다음 포스팅에서 다루도록 하겠습니다.

  1. 파일 확장자를 쓰는 게 왜 esm 문법에 더 맞는 것인가?

  2. export default / named export 의 장단점

  3. hook 앞에 use 라는 prefix 를 제한해둘 수 있는 동작의 근거가 무엇인가? (내부 코드 파악하기)

  4. 내부적으로 fragment 를 만나면 createElement 가 어떻게 동작하는가?

  5. 렌더 트리와 가상돔의 관계

    https://velog.io/@minbr0ther/React.js-Virtual-DOM-가상-돔#2️⃣-virtual-dom의-등장

  6. state update 시, batching 이 되는 시점과 조건

  7. context api / vue의 provide-inject, 전역 상태 관리 라이브러리와의 장단점

  8. 제어 컴포넌트 / 비제어 컴포넌트의 차이

    https://velog.io/@yukyung/React-제어-컴포넌트와-비제어-컴포넌트의-차이점-톺아보기

  9. flushSync 를 언제 사용하는지

    https://ko.react.dev/reference/react-dom/flushSync

profile
프론트엔드에 백엔드 한 스푼 🥄
post-custom-banner

0개의 댓글