[항해 플러스 프론트엔드 7기] 사전 스터디 2주차 - React

Jaehyun Ahn·2025년 9월 24일
0

항해 플러스

목록 보기
4/7

state

React에서 state는 컴포넌트 내에서 데이터와 UI 상태를 관리하는 변수. 컴포넌트 내부에서 바뀔 수 있는 값

state의 특징

  • 값이 바뀌면 해당 컴포넌트가 리렌더링됨
  • 불변성 유지 : state를 수정하기 위해선 직접 수정하는 것이 아닌 set 함수를 통해 변경해야 함

React에서 state를 정의할 땐 useState() hook을 사용


const [value, setValue] = useState(초기값);

불변성

불변성(immutability): 한 번 생성된 데이터는 직접 변경할 수 없다는 의미

  • 원시 데이터(숫자, 문자열, 불리언 등)는 불변
    • 값이 바뀌면 새로운 메모리에 저장되고, 변수는 새 값을 참조
  • 참조형 데이터(객체, 배열, 함수)는 기본적으로 가변
    • 값이 바뀌면 기존 메모리를 직접 수정함

React와 불변성

React는 이전 state와 새로운 state의 메모리 주소를 비교하여 변경 여부를 감지

  • 기존 state를 직접 수정하면 메모리 주소가 변하지 않아 변화 감지 실패 → UI 갱신 X
  • 따라서 state 업데이트 시 불변성을 유지해야 함
    • 배열 → [...prev, newItem]
    • 객체 → { ...prev, key: value }

순수 함수

같은 입력값에 대해 항상 같은 출력값을 반환하고, 외부 상태나 변수에 영향을 미치치 않는 함수


// 순수 함수
function add(a, b) {
  return a + b; // 입력(a, b)에 따라 항상 같은 결과
}


// 순수 함수 X
let count = 0;

function increment() {
  count += 1; // 외부 상태(count)를 변경 → 부작용
  return count;
}

  • React 컴포넌트와 state 업데이트 함수는 순수 함수로 작성해야 예측 가능, 디버깅 쉬워짐
  • 외부 상태를 직접 수정하거나 다른 side effects(HTTP 요청, 쿠키 조작 등)를 발생 시킨다면 UI 예측이 어려워지고 버그 발생 가능성 높아짐

컴포넌트, 렌더링

컴포넌트: UI를 구성하는 단위체
렌더링 : 현재 props와 state 상태에 따라 UI를 그리는 작업

렌더링이 발생하는 조건은

  • 초기 렌더링
  • state가 변경 되었을 때
  • props가 변경 되었을 때
  • 상위 컴포넌트가 렌더링 되면 하위 컴포넌트도 렌더링 됨
  • context 값 변경 (context API 사용 시)

명령형 프로그래밍 vs 선언형 프로그래밍

  • 명령형 프로그래밍 : 무엇을 할지 뿐만 아니라, 어떻게 할지를 구체적으로 기술하는 방식
  • 선언형 프로그래밍 : 무엇을 할지를 기술하고, 어떻게 할지는 시스템이나 언어가 알아서 처리하는 방식
// 명령형

const numbers = [1, 2, 3, 4];
const squared = [];
for (let i = 0; i < numbers.length; i++) {
  squared.push(numbers[i] * numbers[i]);
}
console.log(squared); // [1, 4, 9, 16]


// 선언형

const numbers = [1, 2, 3, 4];
const squared = numbers.map(n => n * n);
console.log(squared); // [1, 4, 9, 16]

React Hooks

useState

컴포넌트의 상태 관리를 가능하게 하는 hook.

  • 컴포넌트가 리렌더링 되더라도 이전 값을 유지.
  • state를 업데이트 하기 위해선 직접 수정하는 것이 아닌 setState 함수를 통해 수정해야 함
  • useState hook으로 원시 타입이 아닌 데이터를 수정 시 불변성을 유지해야함
  • state 초기값으로 모든 타입이 올 수 있음. 초기값 계산이 필요한 경우 함수형 초기값 사용 가능

const [count, setCount] = useState(0)

// state를 변경하는 방법
setCount(1)
setCount((prev) => prev + 1)

일반 업데이트 방식과 함수형 업데이트 방식의 차이는?

  • 일반 업데이트 방법은 setState 함수가 여러개 있더라도 일괄적으로 처리 (불필요한 렌더링을 줄이기 위해 한번에 처리)
  • 함수형 업데이트 방식은 setState 함수를 호출한 만큼 로직이 실행됨

함수형 업데이트 방식이 안정적인 것 같음

useEffect

부수 효과(side effect)를 관리하기 위해 제공되는 hook

  • 컴포넌트가 마운트, 언마운트 됐을 때 실행하고자 하는 함수를 제어할 수 있음
  • 의존성 배열을 통해 hook callback 함수의 실행 조건을 제어할 수 있음
  • useEffect hook을 한 번만 실행하고자 할 때는 의존성 배열을 빈 배열로

부수 효과(side effect
: UI를 그리는 순수 연산이 아닌, 외부 환경에 영향을 주거나 외부 상태를 참조/변경하는 작업

useRef

DOM 요소에 접근할 수 있도록 하는 hook, 데이터를 담아둘 때도 사용함

  • ref에 설정된 값 (current)은 컴포넌트가 계속 렌더링디어도 unmount 전까지 값을 유지함
    • 제어 컴포넌트(state), 비제어 컴포넌트(ref)

useContext

context API를 사용할 때 사용되는 hook

Provider에서 제공한 value가 달라진다면 해당 context를 구독하고 있는 모든 컴포넌트가 리렌더링 됨.

useMemo, useCallback, React.memo

최적화를 위한 hook. 불필요한 렌더링이 발생하지 않도록 하여 최적화를 도움

  • useMemo : 값을 메모이제이션
  • useCallback : 함수를 메모이제이션
  • memo : 컴포넌트를 메모이제이션

라이프 사이클

리액트 컴포넌트가 생성되고 제거될 때 까지의 과정을 의미 Mount - Update - Unmount

  • Mount : 컴포넌트가 생성될 때를 의미 (constructor(), getDerivedStateFromProps(nextProps, prevState), render(), componentDidMount())
  • Update : 컴포넌트가 갱신될 때를 의미 (getDerivedStateFromProps(nextProps, prevState), shouldComponentUpdate(), render(), getSnapshotBeforeUpdate(), componentDidUpdate())
  • Unmount : 컴포넌트가 DOM에서 제거될 때를 의미 (componentWillUnmount)

DOM, Virtual DOM

DOM : 페이지를 구성하는 엘리먼트(컴포넌트)를 tree 형태로 표현한 것

  • tree 요소 하나하나를 '노드' 라고 표현

Virtual DOM : 가상의 DOM, 실제 DOM 구조와 동일한 복사본

  • Virtual DOM 작동 원리
    • 실제 DOM과 동일한 가상의 DOM을 만들어 변경 사항을 반영. 그 후 실제 DOM과 가상 DOM을 비교하여 바뀐 부분만 실제 DOM에 적용.
    • 브라우저의 렌더링 부담을 줄여줄 수 있음. (메모리에서 가상 DOM으로 변경 사항 선 반영 후 바뀐 부분만 실제 DOM에 업데이트 하기 때문)
  • Virtual DOM을 사용하는 이유
    • 사용자 인터렉션이 일어날 때마다 DOM을 조작하게 된다면, 매번 브라우저 렌더링이 실행되고 이는 성능에 많은 영향을 끼치게 됨
      따라서 가상 DOM을 이용해 DOM 처리 횟수를 최소화하고 효율적으로 진행하게 해줌.
profile
미래 프론트 어쩌고

0개의 댓글