공부해봅시당

[Typescript] 상태관리 본문

STUDY/Typescript

[Typescript] 상태관리

tngus 2024. 9. 3. 14:04

상태란?

리액트 공식문서 : 렌더링 결과에 영향을 주는 정보를 담은 순수 자바스크립트 객체

 

시간이 지나면서 변할 수 있는 동적인 데이터이며, 값이 변경될 때마다 컴포넌트의 렌더링 결과물에 영향을 준다.

크게 지역 상태, 전역 상태, 서버 상태로 구분 할 수 있다.

상태의 종류

  • 지역 상태 : 컴포넌트 내부에서 사용되는 상태
  • 전역 상태 : 앱 전체에서 공유하는 상태
  • 서버 상태: 외부 서버에 저장해야 하는 상태

상태 관리시 유의 사항

상태는 애플리케이션의 복잡성을 증가시키고 동작을 예측하기 어렵게 만든다. 또한 상태가 업데이트될 때마다 리렌더링이 발생하기 때문에 유지 보수  및 성능 관점에서 상태의 개수를 최소화하는 것이 바람직한다.

이를 위해서 2가지를 고려해야 한다.

  • 시간이 지나도 변하지 않느다면 상태가 아니다.
  • 파생된 값은 상태가 아니다.

만약 동일 객체 참조를 유지하려는 목적이라면, 해당 값은 상태가 아니므로 useRef를 사용하는 것이 적합하다.

또한 SSOT(Single Source Of Truth)를 생각하여 어떠한 데이터도 단 하나의 출처에서 생성하고 수정해야 한다.

 

상태관리시 useState vs useReducer

useReducer의 경우 2가지 상황에서 권장된다.

  • 다수의 하위 필드를 포함하고 있는 복잡한 상태 로직을 다룰 때
  • 다음 상태가 이전 상태에 의존적일 때

 

  //before
  const [fold, setFold] = useState(true);
  const toggleFold = () => {
    setFold((prev) => !prev);
  };

  //after
  const [fold2, toggleFold2] = useReducer((v) => !v, true);

 

 전역 상태 관리와 상태 관리 라이브러리

상태는 사용하는 곳과 최대한 가까워야 하며 사용범위를 제한해야한다.

 

이때 전역 상태관리를 위해선 컨텍스트 API와 외부 상태관리 라이브러리를 쓸 수 있다.

 

Context API

깊은 레벨에 있는 컴포넌트 사이에 데이터를 전달하는 Prop Drilling 같은 문제를 해결하기 위한 도구로 사용된다.

컨텍스트 API를 활용하면 전역적으로 공유해야 하는 데이터를 컨텍스트로 제공하고 해당 컨텍스트를 구독한 컴포넌트에서만 데이터를 읽을 수 있다.

이때 유틸리티 함수를 만들어 간단하게 쓸 수 있다.

다만 컨텍스트 API를 사용할 경우 해당 컨텍스트를 구독하고 있는 모든 컴포넌트가 리렌더링 되기 때문에, 대규모 에플리케이션이나 성능이 중요한 애플리케이션에서는 권장되지 않는다.

import React, { useContext } from 'react';

type Consumer<C> = () => C;

export interface ContextInterface<S> {
  state: S;
}

export function createContext<S, C = ContextInterface<S>>(): readonly [
  React.FC<C>,
  Consumer<C>
] {
  const context = React.createContext<Nullable<C>>(null);

  const Provider: React.FC<C> = ({ children, ...otherProps }) => {
    return (
      <context.Provider value={otherProps as C}>{children}</context.Provider>
    );
  };

  const useCustomContext: Consumer<C> = () => {
    const _context = useContext(context);
    if (!_context) {
      throw new Error('Context not found');
    }

    return _context;
  };

  return [Provider, useCustomContext];
}

 

Mobx

  • 특징 및 장점
    1. 객체 지향 프로그래밍과 반응형 프로그래밍 패러다임의 영향을 받은 라이브러리
    2. 상태 변경 로직을 단순하게 작성할 수 있고 복잡한 업데이트 로직을 라이브러리에 위임할 수 있다.
  • 단점
    데이터가 언제, 어떻게 변하는지 추적하기 어려움

 

Redux

  • 특징 및 장점
    1. 함수형 프로그래밍의 영향을 받은 라이브러리
    2. 특정 UI 프레임워크에 종속되지 않아 독립적으로 상태 관리 라이브러리를 사용할 수 있음
    3. 상태 변경 추적에 최적화 되어 있음
  • 단점
    단순한 상태 설정에도 많은 보일러 플레이트가 필요함


Recoil

  • 특징 및 장점
    1. 상태 저장할 수 있는 Atom과 해당 상태를 변형할 수 있는 순수 함수 selector를 통해 상태를 관리함
    2.Redux에 비해 보일러플레이트가 적고 난이도가 쉬움
  • 단점
    아직 실험적 상태이기 때문에 충분한 검증이 이루어 지지 않음

Zustand

  • 특징 및 장점
    1. Flux  패턴을 사용하며 많은 보일러플레이트를 가지지 않는 훅 기반의 API모듈을 제공
    2.클로저를 활용하여 스토어 내부 상태를 관리함으로써 특정 라이브러리에 종속되지 않음
    3. 상태와 상태를 변경하는 액션을 정의하고 반환된 훅을 어느 컴포넌트에서나 임포트하여 원하는 대로 사용할 수 있음

배민팀에선 대체적으로 recoil을 선호하신다.

 


출처

https://ungumungum.tistory.com/94

 

우아한 타입스크립트 with React -10장 상태 관리

상태관리 상태란? 리액트 공식문서 : 렌더링 결과에 영향을 주는 정보를 담은 순수 자바스크립트 객체 시간이 지나면서 변할 수 있는 동적인 데이터이며, 값이 변경될 때마다 컴포넌트의 렌더링

ungumungum.tistory.com

 

'STUDY > Typescript' 카테고리의 다른 글

[Typescript] Hook  (0) 2024.09.03
[Typescript] JSX에서 TSX로  (1) 2024.09.03
[Javascript] JSX(JavaScript XML)  (0) 2024.09.03
[Typescript] 비동기 호출  (0) 2024.08.20
[Typescript] 타입스크립트 컴파일  (0) 2024.08.20