엔터프라이즈 애플리케이션을 위한 최고의 React 상태 관리 도구

게시 됨: 2022-03-11

엔터프라이즈 수준의 React 애플리케이션 개발자는 일관된 최종 사용자 경험에 상태 관리가 얼마나 중요한지 알고 있습니다.

그러나 사용자만이 상태 관리의 영향을 받는 것은 아닙니다. React 개발자는 상태를 만들고 유지합니다. 그들은 상태 관리가 간단하고 확장 가능하며 원자적이기를 원합니다. React는 후크를 도입하여 이 방향으로 움직였습니다.

여러 구성 요소 간에 상태를 공유해야 하는 경우 문제가 발생할 수 있습니다. 엔지니어는 필요에 맞는 도구와 라이브러리를 찾는 동시에 엔터프라이즈급 앱에 필요한 높은 표준을 충족해야 합니다.

이 기사에서는 가장 널리 사용되는 라이브러리를 분석 및 비교하고 엔터프라이즈 수준 애플리케이션의 상태 관리에 가장 적합한 라이브러리를 선택합니다.

내장된 React 상태 관리 기능

React에는 여러 구성 요소에 걸쳐 데이터를 제공하는 훌륭한 도구가 있습니다. 컨텍스트의 주요 목표는 소품 드릴을 피하는 것입니다. 우리의 목표는 빈번한 업데이트, 재설계, 새로운 기능 도입 등 엔터프라이즈 애플리케이션에서 발생할 수 있는 다양한 시나리오에서 상태를 관리하는 사용하기 쉬운 도구를 얻는 것입니다.

이 모든 것이 Context로 이론적으로 가능하지만 설정, 지원 및 최적화하는 데 시간이 필요한 맞춤형 솔루션이 필요합니다. Context의 유일한 장점은 타사 라이브러리에 의존하지 않는다는 것입니다.

또한 React 팀 멤버인 Sebastian Markbage는 새로운 Context API가 빈도가 높은 업데이트가 아니라 테마 업데이트 및 인증 관리와 같은 빈도가 낮은 업데이트를 위해 빌드 및 최적화되었다고 언급했습니다.

기존 라이브러리 검사

GitHub에는 수십 개의 상태 관리 도구가 있습니다(예: Redux, MobX, Akita, Recoil, Zusstand). 그러나 각각을 고려하는 것은 끝없는 연구와 비교로 이어질 것입니다. 그렇기 때문에 인기도 , 사용 , 유지 관리자 를 기준 으로 세 가지 주요 경쟁자 로 선택 범위 를 좁혔습니다 .

비교를 명확하게 하기 위해 다음 품질 속성을 사용합니다.

  • 사용성
  • 유지보수성
  • 성능
  • 테스트 가능성
  • 확장성(더 큰 상태에서 동일한 성능으로 작동)
  • 수정 가능성
  • 재사용 성
  • 생태계(기능 확장을 위한 다양한 도우미 도구 보유)
  • 커뮤니티(많은 사용자가 있으며 웹에서 질문에 대한 답변을 제공합니다.)
  • 이식성(React 이외의 라이브러리/프레임워크와 함께 사용할 수 있음)

리덕스

Redux는 2015년에 만들어진 상태 컨테이너입니다. 다음과 같은 이유로 큰 인기를 얻었습니다.

  • 출시 당시에는 심각한 대안이 없었습니다.
  • 그것은 상태와 행동 사이의 분리를 제공했습니다.
  • react-redux 매직은 간단한 상태 연결을 가능하게 했습니다.
  • 라이브러리의 공동 작성자는 호평을 받는 Facebook 개발자이자 React 핵심 팀원인 Dan Abramov입니다.

Redux를 사용하여 리듀서에서 리듀서로의 상태와 동작의 진행을 보여주는 애니메이션.

데이터가 있는 글로벌 저장소 가 있습니다. 스토어를 업데이트해야 할 때마다 reducer 로 이동 하는 작업 을 전달합니다. 작업 유형에 따라 리듀서는 상태를 변경할 수 없는 방식으로 업데이트합니다.

React와 함께 Redux를 사용하려면 react-redux 를 통해 저장소 업데이트에 구성 요소를 구독해야 합니다.

Redux API 예제

코드베이스에서 Redux를 다른 도구와 구별하는 기본적인 부분은 슬라이스입니다. 액션과 리듀서의 모든 로직이 포함되어 있습니다.

코드샌드박스

 // slices/counter.js import { createSlice } from "@reduxjs/toolkit"; export const slice = createSlice({ name: "counter", initialState: { value: 0 }, reducers: { increment: (state) => { state.value += 1; }, decrement: (state) => { state.value -= 1; } } }); export const actions = slice.actions; export const reducer = slice.reducer; // store.js import { configureStore } from "@reduxjs/toolkit"; import { reducer as counterReducer } from "./slices/counter"; export default configureStore({ reducer: { counter: counterReducer } }); // index.js import React from 'react' import ReactDOM from 'react-dom' import { Provider } from 'react-redux' import App from './App' import store from './store' ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') ) // App.js import React from "react"; import { useSelector, useDispatch } from "react-redux"; import { actions } from "./slices/counter"; const App = () => { const count = useSelector((state) => state.counter.value); const dispatch = useDispatch(); return ( <div> <div> <button onClick={() => dispatch(actions.increment())}>Increment</button> <span>{count}</span> <button onClick={() => dispatch(actions.decrement())}>Decrement</button> </div> </div> ); }; export default App;

품질 속성

  • 사용성 . Redux는 공식 툴킷 패키지의 도입으로 매우 간단해졌습니다. 슬라이스(초기 상태, 리듀서 및 작업의 조합)를 만들고 저장소에 전달하고 후크를 통해 구성 요소에서 액세스합니다.
  • 유지보수성 . Redux는 간단합니다. 무언가를 강화하거나 수리하는 방법을 이해하는 데 깊은 지식이 필요하지 않습니다.
  • 성능 . Redux의 주요 성능 영향자는 소프트웨어 엔지니어입니다. Redux는 많은 논리가 필요 없는 간단한 도구입니다. 상태 업데이트가 느린 경우 공식 지침에 따라 더 빠르게 업데이트할 수 있습니다.
  • 테스트 가능성 . Redux는 순수 함수(액션 및 리듀서)로 구성되어 있어 단위 테스트에 적합합니다. 또한 저장소, 작업 및 감속기가 함께 작동하는 통합 테스트를 작성하는 메커니즘을 제공합니다.
  • 확장성 . 기본적으로 Redux는 하나의 전역 상태를 가지므로 확장하기 어렵습니다. 그러나 모듈식 감속기와 미들웨어를 생성할 수 있는 redux-dynamic-modules 라이브러리가 있습니다.
  • 수정 가능성 . Redux를 사용자 정의하는 것은 미들웨어를 지원하기 때문에 쉬운 일입니다.
  • 재사용성 . Redux는 프레임워크에 구애받지 않으므로 재사용성이 매우 뛰어납니다.
  • 생태계 . Redux는 유용한 추가 기능, 라이브러리 및 도구의 거대한 생태계를 제공합니다.
  • 커뮤니티 . 비교 대상에서 가장 오래된 상태 관리 라이브러리인 Redux는 상당한 지식 기반을 갖춘 대규모 커뮤니티를 축적했습니다. 스택 오버플로에는 redux 태그가 포함된 ~30,000개(~19,000개 답변) 질문이 있습니다.
  • 펄스 . Redux는 정기적으로 업데이트되고 유지됩니다.

몹X

MobX는 GitHub에서 별 23,000개를 보유한 비교적 오래된 또 다른 라이브러리입니다. Redux와 다른 점은 OOP 패러다임을 따르고 관찰 가능 항목을 사용한다는 것입니다. MobX는 Michel Weststrate가 만들었으며 현재 Boston에 기반을 둔 Mendix의 도움으로 오픈 소스 애호가 그룹에 의해 유지 관리되고 있습니다.

작업에서 관찰 가능한 상태 및 계산된 값, 부작용에 이르기까지 MobX를 사용한 상태 관리를 나타내는 다이어그램입니다.

MobX에서는 관찰 가능한 저장소 인 생성자 내부에서 makeObservable 호출을 사용하여 JavaScript 클래스를 만듭니다(적절한 로더가 있는 경우 @observable 데코레이터를 사용할 수 있음). 그런 다음 클래스의 속성(상태) 및 메서드( 작업계산된 값 )를 선언합니다. 구성 요소는 이 관찰 가능한 저장소를 구독하여 상태, 계산된 값 및 작업에 액세스합니다.

MobX의 또 다른 필수 기능은 가변성입니다. 부작용을 피하기 위해 상태를 자동으로 업데이트할 수 있습니다.

MobX API 예제

MobX의 고유한 기능은 모든 마법이 숨겨져 있는 거의 순수한 ES6 클래스를 생성한다는 것입니다. 논리에 집중하기 위해 라이브러리별 코드가 덜 필요합니다.

코드샌드박스

 // stores/counter.js import { makeAutoObservable } from "mobx"; class CounterStore { value = 0; constructor() { makeAutoObservable(this); } increment() { this.value += 1; } decrement() { this.value -= 1; } } export default CounterStore; // index.js import React from "react"; import ReactDOM from "react-dom"; import { Provider } from "mobx-react"; import App from "./App"; import CounterStore from "./stores/counter"; ReactDOM.render( <Provider counter={new CounterStore()}> <App /> </Provider>, document.getElementById("root") ); // App.js import React from "react"; import { inject, observer } from "mobx-react"; const App = inject((stores) => ({ counter: stores.counter }))( observer(({ counter }) => { return ( <div> <div> <button onClick={() => counter.increment()}>Increment</button> <span>{counter.value}</span> <button onClick={() => counter.decrement()}>Decrement</button> </div> </div> ); }) ); export default App;

품질 속성

  • 사용성 . 관찰 가능한 저장소는 상태 관리를 위한 단일 진입점입니다. 수정할 수 있는 유일한 장소가 있기 때문에 MobX를 간단하게 사용할 수 있습니다.
  • 유지보수성 . 상당한 단점입니다. RxJS API에 대한 지식이 없으면 원하는 결과를 얻을 수 없습니다. 자격이 부족한 팀에서 MobX를 사용하면 상태 불일치 문제가 발생할 수 있습니다.
  • 성능 . MobX는 독립 상점으로 구성되어 있으며 필요한 것만 구독할 수 있습니다. 매우 효과적입니다.
  • 테스트 가능성 . 관찰 가능한 저장소는 내부에 반응 기능이 숨겨져 있는 일반 JavaScript 객체입니다. 테스트는 다른 JavaScript 클래스와 동일합니다.
  • 확장성 . 관찰 가능한 저장소는 논리적으로 분할됩니다. MobX를 확장하는 데 어려움이 없습니다.
  • 수정 가능성 . MobX를 사용하면 수정된 동작으로 사용자 지정 관찰 가능 항목을 만들 수 있습니다. 또한 반응이라는 개념이 있습니다. 반응은 자동 부작용을 모델링합니다. 이러한 것들은 MobX를 매우 사용자 정의할 수 있게 해줍니다.
  • 재사용성 . MobX는 프레임워크에 구애받지 않으므로 재사용성이 매우 뛰어납니다.
  • 생태계 . MobX에는 수백 가지의 확장 기능을 사용할 수 있습니다.
  • 커뮤니티 . MobX에는 열성적인 팬이 많이 있습니다. 스택 오버플로에 mobx 태그와 관련된 ~1,600개(~1,000개 답변) 질문이 있습니다.
  • 펄스 . MobX는 정기적으로 업데이트 및 유지 관리됩니다.

움찔하다

Recoil은 React 팀의 최신 아이디어인 상대적으로 신참입니다. 기본 아이디어는 공유 상태 및 파생 데이터와 같은 누락된 React 기능의 간단한 구현입니다.

엔터프라이즈 수준 프로젝트에 대해 실험적 라이브러리가 검토되는 이유가 궁금할 것입니다. 우선, Recoil은 현재 React 커뮤니티에서 가장 많이 논의되는 주제 중 하나입니다. 둘째, Recoil은 Facebook의 지원을 받고 있으며 이미 일부 응용 프로그램에서 사용되고 있습니다. 즉, 어느 시점에서 안정적인 버전이 될 것입니다. 마지막으로 React에서 상태를 공유하는 완전히 새로운 접근 방식이며 Recoil이 더 이상 사용되지 않더라도 동일한 경로를 따르는 다른 도구가 있을 것이라고 확신합니다.

반동은 원자선택기 라는 두 가지 용어를 기반으로 합니다. 원자는 공유 상태 조각입니다. 구성 요소는 값을 가져오거나 설정하기 위해 원자를 구독할 수 있습니다.

구성 요소가 값을 검색하거나 설정하기 위해 원자를 구독할 수 있는 방법을 보여주는 Recoil을 사용한 상태 관리를 나타내는 다이어그램.

이미지에서 볼 수 있듯이 값이 변경되면 구독된 구성 요소만 다시 렌더링됩니다. 이것은 Recoil을 매우 성능이 좋게 만듭니다.

Recoil이 즉시 사용할 수 있는 또 다른 기능은 선택기 입니다. 선택자는 원자 또는 다른 선택자에서 집계된 값입니다. 소비자의 경우 atom과 selector의 차이가 없으며 일부 반응 부분을 구독하고 사용하기만 하면 됩니다.

Recoil에서 선택기의 사용, 원자와의 관계, 다른 값으로 인한 변경을 보여주는 다이어그램.

원자/선택기가 변경될 때마다 이를 사용하는(즉, 구독하는) 선택기가 재평가됩니다.

반동 API 예제

Recoil의 코드는 경쟁 제품과 훨씬 다릅니다. React 후크를 기반으로 하며 이 상태를 변경하는 것보다 상태 구조에 더 중점을 둡니다.

코드샌드박스

 // atoms/counter.js import { atom } from "recoil"; const counterAtom = atom({ key: "counter", default: 0 }); export default counterAtom; // index.js import React from "react"; import ReactDOM from "react-dom"; import { RecoilRoot } from "recoil"; import App from "./App"; ReactDOM.render( <RecoilRoot> <App /> </RecoilRoot>, document.getElementById("root") ); // App.js import React from "react"; import { useRecoilState } from "recoil"; import counterAtom from "./atoms/counter"; const App = () => { const [count, setCount] = useRecoilState(counterAtom); return ( <div> <div> <button onClick={() => setCount(count + 1)}>Increment</button> <span>{count}</span> <button onClick={() => setCount(count - 1)}>Decrement</button> </div> </div> ); }; export default App;

품질 속성

  • 사용성 . Recoil은 React의 useState 처럼 작동하기 때문에 사용하기 가장 쉬운 도구 중 하나입니다.
  • 유지보수성 . Recoil에서 해야 할 일은 구성 요소 내부의 선택기와 후크를 유지 관리하는 것뿐입니다.
  • 성능 . Recoil은 React 외부에 상태 트리를 구축합니다. 상태 트리를 사용하면 전체 트리의 변경 사항이 아니라 필요한 사항을 얻고 들을 수 있습니다. 또한 후드 아래에서도 잘 최적화되어 있습니다.
  • 테스트 가능성 . Recoil은 원자와 선택기를 테스트하기 위한 메커니즘을 제공합니다.
  • 확장성 . 여러 개의 독립적인 조각으로 분할되는 상태는 확장성 면에서 좋은 플레이어가 됩니다.
  • 수정 가능성 . Recoil은 값과 그 집계를 저장하는 역할만 합니다. 데이터 흐름이 없으므로 쉽게 사용자 정의할 수 있습니다.
  • 재사용성 . 반동은 React에 의존합니다. 다른 곳에서 재사용할 수 없습니다.
  • 생태계 . 현재 Recoil에 대한 생태계는 없습니다.
  • 커뮤니티 . 반동은 큰 커뮤니티를 갖기에는 너무 신선합니다. 스택 오버플로에는 recoiljs 태그와 관련된 ~70개의 질문이 있습니다.
  • 펄스 . Recoil은 자주 업데이트되지 않습니다(최근 두 업데이트 사이에 6개월 경과). 또한 GitHub에는 많은 미해결 문제가 있습니다.

올바른 React 상태 관리 도구 선택하기

엔터프라이즈급 앱과 관련하여 이러한 React 전역 상태 관리 라이브러리는 어떻게 쌓이나요?

Recoil은 젊고 신선하지만 현재 커뮤니티나 생태계가 없습니다. Facebook이 작업 중이고 API가 유망해 보이지만 거대한 React 애플리케이션은 커뮤니티 지원이 약한 라이브러리에 의존할 수 없습니다. 또한 실험적이기 때문에 더욱 위험합니다. 오늘날 React 엔터프라이즈 애플리케이션에는 확실히 좋은 옵션이 아니지만 계속 지켜볼 가치가 있습니다.

MobX와 Redux는 이러한 문제를 공유하지 않으며 시장에 나와 있는 대부분의 대기업이 이를 사용합니다. 그것들을 서로 다르게 만드는 것은 학습 곡선입니다. MobX는 반응형 프로그래밍에 대한 기본적인 이해가 필요합니다. 프로젝트에 관련된 엔지니어가 충분히 숙련되지 않은 경우 응용 프로그램은 코드 불일치, 성능 문제 및 개발 시간 증가로 끝날 수 있습니다. MobX는 수용 가능하며 팀이 반응성을 알고 있는 경우 요구 사항을 충족할 것입니다.

Redux에는 대부분 확장성과 성능과 관련된 몇 가지 문제가 있습니다. 그러나 MobX와 달리 이러한 문제에 대한 입증된 솔루션이 있습니다.

모든 장점과 단점을 고려하고 내 개인적인 경험을 고려할 때 Redux를 React 엔터프라이즈 수준 응용 프로그램에 대한 최상의 옵션으로 추천합니다.