본문 바로가기

React

[React] 상태 관리 라이브러리 Redux와 Mobx

반응형

상태와 상태관리란?

  • 상태는 웹 페이지 내에서 눈에 보이는 데이터(ex.메뉴, 게시글 제목, 게시글 내용, 아이디) 뿐만 아니라 서버와 주고 받아야하는 모든 데이터를 말함.
  • 화면에 보이는 것과 화면에 보이지 않는 모든 것들을 상태라고 하고 이를 관리하는 것을 상태 관리라고 함.

 

상태관리 라이브러리를 왜 사용할까?

  • SPA 를 개발할 때, 화면에 보이는 상태들이나 화면에 보이지 않는 상태들도 실시간이나 비동기로 변화하기 때문에 상태가 언제 어떻게 변화하였는지 알 수 없어져 컨트롤하기 힘든 상황에 놓이게 됐음.
  • 프로젝트의 규모가 커지고 복잡해지면서 방대한 데이터들을 관리하기 어려워짐.
  • Component 간의 정보 공유

     - 자식 컴포넌트 간의 다이렉트 데이터 전달이 불가능

     - 자식 컴포넌트들 간의 데이터를 주고 받을 때 상태를 관리하는 부모 컴포넌트를 통해 데이터 전달

     - But 자식 컴포넌트가 많아진다면 상태 관리가 매우 복잡

     - 상태를 관리하는 상위 컴포넌트에서 계속 내려 받아야 함 = Props drilling 

   

=> 전역 상태 저장소 제공

 

 

인기

: npm trends에 따르면 21년 11월 현재 Mobx보다 Redux가 훨씬 더 많은 다운로드 수를 기록하고 있음

 

 

 


 

 

1. Redux 

: 가장 유명한 상태 관리 라이브러리로 MVC 패턴의 문제점을 극복하고자 페이스북에서 고안한 Flux 아키텍처를 기반으로 구현

 * Flux는 앱의 데이터 흐름을 관리하는 패턴, 데이터의 흐름이 단방향

 

 

스토어(Store): 상태가 관리되는 오직 하나의 공간

 - 컴포넌트와는 별개로 스토어라는 공간이 있어서 그 스토어 안에 앱에서 필요한 상태를 담음

 - 컴포넌트에서 상태 정보가 필요할 때 스토어에 접근

 - 스토어 안에 하나뿐인 데이터의 공간이 있음

 

액션(Action)

 - 앱에서 스토어에 운반할 데이터를 말함

 - 자바스크립트 객체 형식으로 구성

{
	type:'ACTION_CHANGE_USER', //필수
    payload: { // 옵션
    	name: '리덕스',
        age: 10
      }
 }

리듀서(Reducer)

- 액션(Action)을 스토어(Store)에 바로 전달 하는 것이 아니라 리듀서(Reducer)에 전달해야 함

- 리듀서(Reducer)가 주문을 보고 스토어(Store)의 상태를 업데이트 하는 것

- 액션(Action)을 리듀서(Reducer)에 전달하기 위해서는 dispatch() 메소드를 사용

 

예제 소스

 

import { Provider } from 'react-redux'; // redux 설치/셋팅
import { createStore } from 'redux';

const 키 = 100; // state 맘대로 보관 가능
	                              // action은 dispatch를 통해 보낸 데이터를 의미
function reducer(state = 키, action){ // state를 사용할 각 컴포넌트에서 관리하는 것 보다 Store에서 함수로 만들어 필요한 컴포넌트에서 사용하면 편리함
 if (action.type === '증가'){ // reducer라고 부름
 	state++;
    return state
  } else if (action.type === '감소'){
  	state--;
    return state
  } else {
  	return state
  }
  
  }

 

import { useDispatch, useSelector } from 'react-redux'

function App() {

   const 받아온것 = useSelector( (state) => state ); // store에 있던 state를 컴포넌트에서 사용
    	                           // props 없이 state를 직접 꺼낼 수 있음
   const dispatch = useDispatch() // state 수정요청할 때 필요
    
    return ( 
    	<div className="App">
        	<p> 키 : {받아온것} </p>
            <button onClick={()=> { dispatch({type : '증가'}) }}> 더하기 </button> //type 요청 명
            <butoon onClick={()=> { dispatch({type : '감소'}) }}> 빼기 </button> //type 요청 명
        </div>
      );
    }
    
 export default App;

 

장점

  • 단방향 모델링 - action을 dispatch 할 때 마다, 기록이 남아서 에러를 찾아내기 편함
  • 읽기 전용 상태 - 상태를 변경하기 위해서는 상태 일부를 변경하는 것이 아니라 전체를 변경해야 하기 때문에 이전 상태에서 현재 상태로 덮어쓰기만 하면 됨
  • 상태의 중앙화 - 스토어(Store)라는 이름의 전역 자바스크립트 변수를 통해 상태를 한 곳에서 관리

단점

  • 높은 러닝 커브
  • Redux의 규칙때문에 오히려 코드가 복잡해지거나 어려워질 수도 있기 때문에 프로젝트의 상황에 따라 적절한 라이브러리를 사용하는 것이 나을 수도 있음

 


 

2. Mobx

: 사용하기 쉽고 강력한 기능으로 꾸준한 성장을 하고 있는 상태관리 라이브러리

  렌더링 할 State를 관찰대상으로 지정, State를 변경하면 React Component Render 메소드에 의해서 Rerendering되는   아키텍쳐를 기본 골격

 

 

 

 

"배달 리스트를 가져오기 위해서 DeliveryStore(Spring의 서비스의 역할과 거의 비슷)의 findAllDeliveries를 호출하여 서버로 부터 가져온 데이터를 선언해둔 deliveries state에 할당 해주면 DeliveryComponent에서 deliveries 를 Rendering 하게 되는데 이것이 기본 동작 개념입니다. 기타 Mobx Store React 컴포넌트를 연결하는 방법은 Redux와 달리 @inject 데코레이더 한줄로 이루어 짐."

 

 

장점

  • 객체지향적 - ES6에서 추가된 Class를 이름 뿐만 아니라 객체지향적으로 사용하고 개발을 권장
  • 서버개발자들에게 친숙한 아키텍쳐 - Java Spring Framework와 유사한 아키텍쳐구조를 지향하고 있어 서버개발자들에게 보다 친숙하고 낮은 러닝 커브를 제공, 장점을 그대로 적용할 수 있음
  • 캡슐화 - Mobx Configuration 설정으로 State를 오직 메소드를 통해 변경할 수 있도록 Private하게 관리 가능함
  • 불변성 유지를 위한 노력이 불필요 - 복잡한 코드나 Immutable.js 와 같은 라이브러리를 따로 사용할 필요가 없음

단점

  • 사용자가 상대적으로 적다보니 레퍼런스가 부족함
  • 디버깅 툴이 불편함

 

특징

  • Redux를 사용할 때 React Component와 state를 연결하기 위한 mapStateToProps, Redux action을 연결하기 위한 mapDispatchToProps, bindActionCreators 등등 보일러플레이트 코드가 사라지고 데코레이터로 처리하기 때문에 깔끔한 코드가 생성

* 보일러플레이트 코드란? 개발자들에게 불필요하고 복잡하고 도움이 안 되는 반복적인 일들을 하지 않도록 도와주는 것 ex) getter/setter

 

 

Mobx Spring
Store Service
Model Class Entitiy or Dto
Repository Class Repository

 

스토어(Stroe)

- @observable(관찰 가능한)로 지정하여 React Component에서 렌더링될 state로 사용, React Component에서 사용할 Mobx Store의 Dependency Injection은 @inject 데코레이터 하나로 끝남

 

 

모델(Model)

- Java Spring에서 DTO를 선언하는 것과 유사, 차이점이라면 JavaScript 특성상 프로퍼티를 미리 추가하지 않고 동적으로 추가할 수 있어서 그냥 동적으로 추가한 것

- 도메인 자신의 값과 자신의 값을 핸들링하는 메소드를 가지고 있는 형태로 구성

 

 

레파지토리(Repository)

- Ajax로 데이터를 가져오는 부분, 데이터를 가져오는 부분도 Layer를 나누어 구성하는 것을 권장

- API 호출을 담당하는 Repository 성격의 Class를 만들고 Mobx Store에서 async 또는 generator를 사용해서 간단하게 callback 메소드 없는 패턴으로 구현되기 때문에 가독성도 좋음, 추가 라이브러리 필요없음.

 

 

반응형

'React' 카테고리의 다른 글

React map() 함수 정리  (0) 2021.12.22
전자정부 프레임워크 front-end react  (0) 2021.12.17
axios 개념과 http method 종류  (0) 2021.11.16
Props와 State 개념 정리  (0) 2021.11.11
DOM, Virtual DOM이란?  (0) 2021.11.09