[Article] 상태관리의 중요성

장명지·2023년 1월 24일

아티클

목록 보기
2/13

리액트를 공부하면서 가장 많이 들었던 말이 '상태관리'이다. 상태관리란 무엇이고 어떻게 관리하는 것이 좋은 것인지 짧게나마 이야기해보고자 한다!

상태관리란?

프론트엔드에서 상태란 "화면에 영향을 주는 자바스크립트 객체"이다. 즉, 계속해서 "변화하는 데이터"를 말한다. 주로 페이지 렌더링과 UI작업을 처리한다.

상태관리의 필요성

리액트는 data를 전달할 때 data를 부모 컴포넌트로 보내고 자식 컴포넌트에서 받아야하는데 자식컴포넌트끼리 data를 전달하고 싶다면 부모 컴포넌트에서 props로 다시 연결해주어야 한다. 하지만 이때 하나, 두개의 컴포넌트가 아닌 그 개수가 증가하다보면 props 무한 지옥이 이어지게 되고 이것을 과도한 Props Drilling이 되었다고 한다. 이렇게 되면 이 props가 어디서 시작되었는지 알기 어려워지고 리액트의 장점인 유지보수가 쉽다는 점도 없어지게 된다.

import React from "react";
import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <FirstComponent content="I'm PropsDrilling" />
    </div>
  );
}

function FirstComponent({ content }) {
  return (
    <div>
      <h3>I am the first component</h3>;
      <SecondComponent content={content} />|
    </div>
  );
}

function SecondComponent({ content }) {
  return (
    <div>
      <h3>I am the second component</h3>;
      <ThirdComponent content={content} />
    </div>
  );
}

function ThirdComponent({ content }) {
  return (
    <div>
      <h3>I am the third component</h3>;
      <ComponentNeedingProps content={content} />
    </div>
  );
}

function ComponentNeedingProps({ content }) {
  return <h3>{content}</h3>;
}
.
.
.

상태의 종류

상태는 크게 범위의 개념에서 전역상태(Global State)컴포넌트 간 상태(Cross Component State) 그리고 지역상태(Local State)로 나눌 수 있다.

  • 지역상태는 특정 컴포넌트 안에서만 관리되는 상태를 말한다. 다른 컴포넌티들과 데이터를 공유하지 않는다는 특징이 있다. input, selectbox 등에서 사용자의 입력값을 경우와 Form 데이터가 그 예이다.
  • 컴포넌트 간 상태는 여러가지 컴포넌트에서 관리되는 상태를 나타내는데 props를 넘겨 쓰인다. 따라서 Prop Drilling 방식을 사용한다. 모달 같은 것이 그 예이다.
  • 전역상태는 프로젝트 전체에 영향을 끼치는 상태이다. 이것도 Prop Drilling 방식이 사용되고 유저기능 같은 것이 그 예이다.

상태관리 툴

Context API
Context API는 리액트에서 만든, React 컴포넌트 트리 안에서 전역 상태를 공유할 수 있도록 만들어진 방법이다.
Context API는 Context, Provider, Consumer가 있는데 Context는 전역 상태를 저장하는 곳으로 이 안에 Provider와 Consumer가 정의되고 Consumer는 COntext를 통해 상태에 접근한다. Provider는 전역 상태를 제공하는 역할로 Context에 상태를 제공해서 다른 컴포넌트가 상태에 접슨 할 수 있도록 도와준다. 이때 모든 컴포넌트에 접근해야하는 상태를 제공하기 위해서는 Root 컴포넌트에서 Provider를 정의한다. Consumer는 제공받은 전역 상태를 받아서 사용하는 역할로 Context는 Consumer 사이에 있는 첫 객체를 Context에 인자로 전달하기 때문에 JSX를 작성하면 안되고, 빈 객체를 작성하고 나서 JSX를 작성해야한다.

이것은 프로젝트의 컴포넌트 구조가 꽤 간단하고 다루는 상태의 종류가 그다지 많지 않다면, 굳이 Context를 사용할 필요는 없다. 하지만 전역적으로 여기저기서 사용되는 상태가 있고 컴포넌트의 개수가 많은 상황이면 이것의 사용을 추천한다.

Redux
리덕스는 전역상태관리를 위한 도구로 어플리케이션 전체에 대한 중앙 저장소 역할을 한다. 이것은 리액트에서 사용하려고 만들어졌지만, 리액트에 종속되는 라이브러리가 아니고, 다른 UI 프레임워크나 라이브러리에서도 사용가능하다.
<리덕스를 사용할 때 지켜야 할 세가지 규칙>
1. 단일 스토어

  • 하나의 어플리케이션에는 하나의 스토어가 들어있다. 여러 갸의 스토어를 사용하는 것이 완전히 불가능하지는 않지만 특정 업데이트가 너무 빈번하게 일어나거나 애플리케이션의 특정 부분을 완전히 분리시킬 때는 여러 개의 스토어를 만들 수 있다. 하지만 상태 관리가 복잡해질 수 있어 권장하지 않는다.
  1. 읽기 전용 상태
  • 상태를 업데이트할 때 기존의 객체는 건드리지 않고 새로운 객체를 생성해 주어야 한다. 그 이유는 내부적으로 데이터가 변경되는 것을 감지하기 위해 얕은 비교 검사를 하기 때문이다. 객체의 변화를 감지할 때 객체의 깊숙한 안쪽까지 비교하는 것이 아니라 겉 핥기 식으로 비교하여 좋은 성능을 유지할 수 있는 것이다.
  1. 리듀서는 순수한 함수
  • 변화를 일으키는 리듀서 함수는 순수한 함수여야 한다. 순수한 함수란 다음 조건을 만족한다.
    • 리듀서 함수는 이전 상태와 액션 객체를 파라미터로 받는다.
    • 파라미터 외의 값에는 의존하면 안된다.
    • 이전 상태는 절대로 건드리지 않고, 변화를 준 새로운 상태 객체를 만들어서 반환한다.
    • 똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결과 값을 반환해야 한다.

Rcoil
recoil은 리액트 프로젝트를 위한 많은 전역 상태관리 라이브러리들 중 하나로 다른 라이브러리와 달리 리액트 전용이자, 리액트에 최적화되어 있다. <기존 리덕스의 문제점>

  • 리액트 전용 라이브러리가 아니기 때문에 동시성모드를 구현하기에 호환성이 부족했다.
  • 복잡한 Boiler Plate 초기 세팅이 요구된다. Store, Action, Reducer 등 다양한 구성요소가 필요해 비효율적이고 러닝 커브가 높다.
  • 비동기 데이터에 추가 리소스가 요구되어 Redux-saga 등 전역상태에 비동기 데이터를 호출하기 위한 서드 파티 라이브러리가 필요하다.
    recoil은 이러한 문제점을 해결하고 사용자 경험 관점에서 매우 유리한 웹 어플리케이션을 만들 수 있도록 도와준다.
    recoil은 전역상태의 설정과 정의가 매우 쉽고 recoil이 지원하는 Hooks로 이를 get/set하기 때문에 react 문법과 매우 유사하다. 그리고 recoil 디렉토리만 필요하기 때문에 Boiler Plate 양이 매우 적고 Hooks기반으로 매우 심플하며 허닝커브가 낮다는 장점이 있다.
    Atom
  • atom은 하나의 상태의로 컴포넌트가 구독할 수 있는 React state다. atom의 값을 변경하면 그것을 구독하고 있는 컴포넌트들이 모두 다시 렌더링 되고, atom을 생성하기 위해 어플리 케이션에서 고유한 키값과 디폴트 값을 성정해야한다.
    useRecoilState
  • atom의 값을 구독하여 업데이트할 수 있는 hook으로 useState와 동일한 방식으로 사용한다.
    useRecoilValue
  • setter 함수 없이 atom의 값을 반환만 한다.
    useSetRecoilState
  • setter 함수만 반환한다.
    selector
  • seletor는 상태에서 파생된 데이터로, 다른 atom에 의존하는 동적인 데이터를 만들 수 있게 해준다.

과거에는 데이터를 Backend 개발자가 관리하였지만, FE 개발자의 관리 영역으로 일부 들어온 만큼 FE 개발자들의 역량이 커졌다고 생각한다. 우리에게 주어진 부분이 많아진 만큼 사용자를 위해 좀 더 빠르고 편리한 서비스를 개발하기 위해 상태관리에 좀 더 많은 공부가 필요하다는 것을 알게되었다. 빠른 시일 내 실습도 함께 해보면서 더 좋은 방법이 무엇인지 고민해봐야겠다!


참고
https://mingule.tistory.com/74
https://ui.toast.com/weekly-pick/ko_20200616
https://abangpa1ace.tistory.com/212
[책] 리액트를 다루는 기술

profile
성장 기록!

0개의 댓글