상태 관리 라이브러리 Redux

wool·2022년 9월 1일
0

React

목록 보기
2/3

React의 데이터 상태관리

state와 props로 데이터의 상태 관리를 할 경우 props drilling현상이 발생하게 되어

많은 컴포넌트 사이에서 props찾기로 인해 불필요한 리소스가 발생한다는 문제점이 있었다.

하지만 react로 데이터의 상태 관리를 하게 될 경우 props drilling의 문제 뿐만 아니라 더 많은 단점이 있다. 그 단점은 다음과 같다

  1. props drilling과 관련된 내용으로 해당 상태를 직접 사용하지 않는 최상위 컴포넌트와 그아래의 컴포넌트들도 상태 데이터를 갖는다.

  2. props drilling이 갖는 문제로 프로퍼티 내려꽂기가 여러번 반복적으로 진행됨

  3. 애플리케이션이 복잡해질수록 데이터 흐름도 매우 복잡해진다.

  4. 컴포넌트 구조가 바뀔 경우 데이터의 흐름이 꼬이게 되어 데이터 흐름을 다시 대거 수정해야 한다.

    이러한 문제점들을 보완하기 위해 상태 관리 라이브러리를 사용하는데

상태 관리 라이브러리의 가장 기본이라고 할 수 있는 Redux를 알아보기로 한다!

Redux

redux는 기존 react의 데이터 흐름과 같지 않고 스토어가 만들어지고 그 스토어 에서 바로 필요한 컴포넌트로 데이터가 전달 될 수 있도록 구성되어있다.

store에서 데이터를 관리하여 필요한 component에 바로 보내 줄 수 있는 시스템을 갖고 있다!

그렇다면 어떤 순서와 구조로 동적으로 변하는 데이터가 전달 되는지 확인 해 보도록 한다.

redux의 구조

상태가 변경 되어야 하는 이벤트가 발생하면 변경 될 상태에 대한 정보가 담긴 기존 데이터의 Action 객체가 생성된다.

Action 객체는 Dispatch 함수의 인자로 전달된다. Dispatch함수는 Action 의 객체를 Reducer 함수로 전달한다.

Reducer함수는 Action객체의 값을 확인한 후 그 값에 따라 전역 상태 저장소 Store의 상태를 변경한다.

상태가 변경되면 변경된 데이터를 화면에 렌더링 한다.

즉, Action → Dispatch → Reducer → Store의 순서로 데이터가 단방향으로 흐르게 된다.

그렇다면 도식이 아닌 어떤 방식으로 코드가 구성되는지 알아보자!

Store, Reducer, Action, Dispatch 개념들을 코드로 구성하기

1. Store

Store는 상태가 관리되는 오직 하나뿐인 저장소이다.

  • store생성 예시코드 createStore 메서드를 활용해서 Reducer를 연결하여 생성 할 수 있다.
    import { createStore } from 'redux';
    
    const store = createStore(rootReducer);

2. Reducer

Reducer는 Dispatch에게서 전달받은 Action 객체의 type값에 따라서 상태를 변경시키는 함수

  • Reducer 예시코드
    const count = 1
    
    // Reducer를 생성할 때에는 초기 상태를 인자로 요구합니다.
    const counterReducer = (state = count, action) => {
    
      // Action 객체의 type 값에 따라 분기하는 switch 조건문입니다.
      switch (action.type) {
    
        //action === 'INCREASE'일 경우
        case 'INCREASE':
    			return state + 1
    
        // action === 'DECREASE'일 경우
        case 'DECREASE':
    			return state - 1
    
        // action === 'SET_NUMBER'일 경우
        case 'SET_NUMBER':
    			return action.payload
    
        // 해당 되는 경우가 없을 땐 기존 상태를 그대로 리턴
        default:
          return state;
    	}
    }
    // Reducer가 리턴하는 값이 새로운 상태가 됩니다.
    이 때, Reducer는 순수함수여야한다. 외부 요인으로 인해 기대한 값이 아닌 엉뚱한 값으로 상태가 변경되는 일이 없어야 하기 때문! 만약 여러 개의 Reducer를 사용 할 경우, Redux의 combineReducers 메서드를 사용해서 하나의 Reducer로 합쳐줄 수 있다.
    • combineReducers 예시코드
      import { combineReducers } from 'redux';
      
      const rootReducer = combineReducers({
        counterReducer,
        anyReducer,
        ...
      });

3. Action

Action어떤 액션을 취할 것인지 정의해 놓은 객체이다.

  • Action 예시코드
    // payload가 필요 없는 경우
    { type: 'INCREASE' }
    
    // payload가 필요한 경우
    { type: 'SET_NUMBER', payload: 5 }
    • Action 작성 시 주의 사항
      1. type지정 : 해당 Action 객체가 어떤 동작을 하는지 명시해주는 역할을 하기 때문에

      2. 대문자와 Snake Case로 작성

      3. 필요에 따라 payload를 작성하여 구체적인 값을 전달

        // payload가 필요 없는 경우
        const increase = () => {
          return {
            type: 'INCREASE'
          }
        }
        
        // payload가 필요한 경우
        const setNumber = (num) => {
          return {
            type: 'SET_NUMBER',
            payload: num
          }
        }
☝ Action을 직접 작성하기보다는 Action 객체를 생성하는 함수를 만들어 사용하는 경우가 많다. 이런 함수를 액션 생성자(Action Creator) 라고도 한다.

4. Dispatch

Dispatch는 Reducer로 Action을 전달해주는 함수

Dispatch의 전달 인자로 Action 객체가 전달 된다.

  • Dispatch 예시 코드
    // Action 객체를 직접 작성하는 경우
    dispatch( { type: 'INCREASE' } );
    dispatch( { type: 'SET_NUMBER', payload: 5 } );
    
    // 액션 생성자(Action Creator)를 사용하는 경우
    dispatch( increase() );
    dispatch( setNumber(5) );
    • Action 객체를 전달받은 Dispatch 함수는 Reducer를 호출한다.

Redux Hooks

Redux Hooks는 React-Redux에서 Redux를 사용할 때 활용할 수 있는 Hooks 메서드를 제공한다.

그 중에서 크게 useSelector(), useDispatch()이 두 가지의 메서드를 기억하도록 한다.

useDispatch()

Action 객체를 Reducer로 전달해 주는 Dispatch 함수를 반환하는 메서드

  • 예시코드
    import { useDispatch } from 'react-redux'
    
    const dispatch = useDispatch()
    dispatch( increase() )
    console.log(counter) // 2
    
    dispatch( setNumber(5) )
    console.log(counter) // 5

useSelector()

컴포넌트와 state를 연결하여 Redux의 state에 접근할 수 있게 해주는 메서드

  • 예시코드
// Redux Hooks 메서드는 'redux'가 아니라 'react-redux'에서 불러옵니다.
import { useSelector } from 'react-redux'
const counter = useSelector(state => state)
console.log(counter) // 1
profile
허위 정보 발견 시 댓글로 남겨주시면 감사하겠습니다.

0개의 댓글