[Redux] 컴포넌트에서 스토어로 상태값 저장하기

GY·2021년 11월 6일
0

리액트

목록 보기
19/54
post-thumbnail
post-custom-banner

🎁 Redux

predictable state container for JS apps
상태관리 라이브러리

React의 한계

리액트는 데이터 변화에 따른 렌더링을 관리하기 위한 라이브러리이다.
UI를 컴포넌트로 나누어 구현할 때 state을 관리하는 것이 어려워지는 문제가 있으며, 이 state에 대한 데이터를 일일히 각 컴포넌트로 전달하는 것 또한 번거롭다.

리덕스는 상태관리를 위한 JS라이브러리로, 이런 문제를 해결해줄 수 있다.

조금 더 자세히 살펴보자.


리액트를 사용해 프로젝트를 하다보면, 하위 컴포넌트로 props의 형태로 필요한 데이터를 전달한다.

컴포넌트가 많아질 수록 계속해서 하위 컴포넌트를 통해 데이터를 전달하는 번거로움이 생길 뿐더러 독립적으로 데이터를 읽거나 수정해 업데이트하기 어렵다. 특히 하위컴포넌트가 상위 컴포넌트에 있는 데이터를 바로 읽어올수가 없다.

컴포넌트와 독립적으로 상태관리하기

Redux는 store라는 상태관리를 위한 전역적인 컨테이너를 생성해 사용한다.
즉, 컴포넌트의 바깥에서 독립적으로 상태값을 관리할 수 있다.

🎁 Redux data flow


store는 state 데이터와 reducer 메서드를 가진다. 데이터를 수정할 때 컴포넌트는 action을 dispatch하고, 필요한 데이터를 가져온다.

store

상태를 저장하는 곳으로, state을 감싸주는 역할.
store안에는 많은 메서드들이 있는데, 이 메서드를 이용해 state을 관리할 수 있다.

store는 state 데이터와 reducer 메서드를 가진다. 데이터를 수정할 때 컴포넌트는 action을 dispatch하고, 필요한 데이터를 가져온다.

const store = {
    "State":{
        "session": data,
        "other": things
    },
    "Reducer":{
        "sessionReducer": func to change session data,
        "otherReducer": func to change other data
    }
}

Action (store에 전달할 메세지)

객체 형태로, 무엇이 일어났는지 설명한다.

dispatch (state 수정 인터페이스)

상태를 변경할 때 dispatch가 store에게 어떤 변경을 할것인지에 대한 정보를 담아 호출한다.

Reducer (action 해석기)

이전 state과 action object를 받은 후에 next state을 return 한다.

(previousState, action) => nextState

이전 상태값이 previousState이 action을 통해 어떤 다음상태 nextState이 되었는지를 나타낸다.

🎁 과정

  • 스토어는 상태를 가지고 있다.
  • 컴포넌트는 디스패치 함수를 통해 액션을 리듀서로 전달한다.
  • 상태는 리듀서에 의해서만 변경이 가능하며, 컴포넌트는 이 상태를 구독한다.
  • 추가적으로 미들웨어는 리듀서와 액션 사이에서 특정 역할을 사용하며 비동기 작업등을 처리한다.


🎁 사용법

state 정의

초기 값을 0으로 설정했다.

export const INIT_COUNT_STATE = {
    value: 0
};

action 정의

action(store에 전달할 메세지)은 객체 형태로, 무엇이 일어났는지 설명한다.
상태값이 변경되는 action을 정의하는 단계
여기서는 action에서 초기값을 + 혹은 -하는 증감함수를 각각 정의한다.

export const INCREMENT = 'INCREMENT'
export const DECREMENT = 'DECREMENT'

export function increment() {
    return {
        type: INCREMENT
    };
}

export function decrement() {
    return {
        type: DECREMENT
    };
}

reducer 생성

(action 해석기)
이전 state과 action object를 받은 후에 next state을 return 한다.

(previousState, action) => nextState

이전 상태값이 previousState이 action을 통해 어떤 다음상태 nextState이 되었는지를 나타낸다.
앞서 정의한 상태값으로 초기화 하고, 액션에 의해 상태값을 변화시키는 내용이 작성된다.

즉, 앞서 정의한 초기값과 액션을 인자로 가져온 다음, 액션의 type에 따라 어떻게 이 초기값/상태를 변화시킬지 내용을 작성해준다.

여기서는 0이라는 초기값에서 시작한 상태를 action의 상태가 Increment일 때는 state++을, Decrement일 때는 state--을 해주도록 상태변경방법을 정의했다.

import { INIT_COUNT_STATUS } from '../status/count'
import { INCREMENT, DECREMENT } from '../actions/count';
import { combineReducers } from 'redux';

function counter (state = INIT_COUNT_STATUS, action) {
    switch(action.type) {
        case INCREMENT:
            return {
                ...state,
                value: state.value + 1
            }
        case DECREMENT:
            return {
                ...state,
                value: state.value - 1
            }
        default:
            return state
    }
}

const counterReducer = combineReducers({ counter });

export default counterReducer

combineReducers는 여러개의 서브 리듀서를 하나로 합쳐준다. 이 과정에서 함수에 객체를 전달하며, 객체 구조에 따라 합쳐진 리듀서의 상태의 구조가 만들어진다.

store 연동

store의 구성이 완료된 상태로, 이를 컴포넌트에서 사용해야 한다. provider로 반드시 감싸주어야 사용할 수 있다. 그리고 상태값을 구독하는 컴포넌트에서는 connect라는 함수를 사용하게 된다.


import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider  } from 'react-redux';

import App from './App';
import CountReducer from './redux/reducer/count';

const store = createStore(CountReducer);

ReactDOM.render(
  <Provider store = { store }>
    <App />
  </Provider>,
  document.getElementById('root')
);

🎁 setting

다운 받아야 하는 Dependencies

  1. redux
  2. react-redux
  3. redux-promis
  4. redux-thunk


Reference

profile
Why?에서 시작해 How를 찾는 과정을 좋아합니다. 그 고민과 성장의 과정을 꾸준히 기록하고자 합니다.
post-custom-banner

0개의 댓글