React

#15 Redux part1

Sila 2022. 5. 7. 00:29

리덕스에 대해 알아보자.

 

리덕스란 리액트의 상태를 관리해주는 라이브러리다.

 

리덕스를 사용하면 컴포넌트의 상태 업데이트 관련 로직을 다른 파일로 분리할 수 있어

 

더 효율적인 관리가 가능하다.

 

그렇다고 리액트에 종속된 라이브러리는 아니다. 단독으로 사용으로 하거나, 다른 것과 같이 써도 된다.

 

이번에는 redux만을 사용해 state를 어떻게 관리하는지 가장 쉬운 예시로 알아보도록 하자.

 

1.용어 정리

우선 state 관리에 관련된 용어를 다시 정리하고 넘어간다.

 

1.1 action

action은 state의 변화를 야기하는 첫 번째 단계이다.

 

객체 형태로 전달되며 여기서 type은 반드시 들어간다. 그 이외의 값은 payload로, 이는 필수적이지는 않다.

 

/*  action 객체의 예시  */

{
    type : 'GET_COFFEE',
    date : {
             id: 1,
             text: 'order coffee'
           }
}

 

이 action 객체를 함수를 이용해 만들어주기도 한다. 

 

/*  action 객체 생성 함수의 예시  */

changeInput = (text) => {
    type: 'GET_COFFEE',
    date: { id:1, text:'order coffee' }
}

 

이렇게 함수를 통해 action을 생성하면 매개변수를 통해 우리가 전달하는 값이 무엇인지

 

좀 더 보기 편하다는 장점이 있다.

 

1.2. reducer

action을 받아 state의 변화를 실행하는 함수이다. useReducer와 비슷하게 작동한다.

 

action의 type, payload를 받아 그걸 기반으로 state를 업데이트한다.

 

/*  reducer 함수 예시  */

function reducer(state = initialState, action) {
    switch(action.type) {
        case GET_COFFEE :
            return {
                coffee: state.coffee + 1
            }
        default :
            return state
    }
}

 

1.3 store

프로젝트에 redux를 저장하기 위해 store를 만든다. 하나의 프로젝트는 하나의 store만을 가질 수 있다.

 

store 안에 현재 app state, reducer, 그 외의 내장 함수가 존재한다.

 

이건 이따가 아래에서 구체적으로 어떻게 사용되는지 알아보자.

 

1.4 dispatch

store의 내장 함수 중 하나이다. acton을 발생시키는 것이라고 생각하면 된다.

 

우리가 dispatch를 호출하면 store가 reducer 함수를 실행하고, state를 업데이트한다.

 

 

2. redux 활용해보기

redux를 npm으로 설치한다.

npm init -y
npm i redux

 

redux를 가져온 후, 이를 출력해보자.

 

const redux = require('redux')

console.log(redux)

 

{
  (...중략)
  applyMiddleware: [Function: applyMiddleware],
  bindActionCreators: [Function: bindActionCreators],
  combineReducers: [Function: combineReducers],
  compose: [Function: compose],
  createStore: [Function: createStore],
  legacy_createStore: [Function: createStore]
}

 

그러면 이렇게 결과가 나올텐데, 이 함수들을 통해 redux의 기능을 사용하는데,

 

이 중 먼저 배워볼 것은 createStore 함수이다.

 

2.1 createStore

우선 이 함수를 이용해 store를 만들기 전에, 그 안에 넣어 줄 reducer와 state, action을 먼저 만들어야한다.

 

const redux = require('redux')

const initialState = {
    name : 'sila',
    coffee : 0
}

const SETUP = 'setup'
const CHANGE_NAME = 'change_name'
const GET_COFFEE = 'get_coffee'
const ORDER = 'order'

const setup = () => ({ type: SETUP })
const change_name = () => ({ type : CHANGE_NAME })
const get_coffee = () => ({ type : GET_COFFEE })
conse order = (payload) => ({ type: ORDER, payload })


const reducer = (state=initialState, action) => {
    switch(action.type) {
        case SETUP :
            return ({
                ...state,
                name: 'sila',
                coffee : 0
            })
        case CHANGE_NAME :
            return({
                ...state,
                name:'alpha'
            })
        case GET_COFFEE :
            return ({
                ...state,
                coffee : state.coffee + 1
                }
        case ORDER :
            return {
                ...state,
                coffee : state.coffee + action.payload
            }
        default : {
            return state
        }
    }
}

 

reducer 는 action과 state 값을 받아 state 값을 업데이트 해준다. 이제 이 reducer를 store 안에 넣어준다.

 

const redux = require('redux')
const { createStore } = redux

(...중략)

const store = createStore(reducer)

 

왜 굳이 createStore 함수에 reducer를 넣고 그걸 store 변수 안에 넣어야 하는지 설명하기 위해,

 

우선 이 아래에 store 변수를 console.log로 확인해보면 다음과 같이 함수를 모아둔 객체가 나온다.

 

console.log(store)

{
  dispatch: [Function: dispatch],
  subscribe: [Function: subscribe],
  getState: [Function: getState],
  replaceReducer: [Function: replaceReducer],
  '@@observable': [Function: observable]     
}

 

보다시피 store 안에 action을 전달해주는 dispatch함수, state를 확인할 수 있는 getState 함수 등이 존재한다.

 

그렇기 때문에 redux에서는 useReducer 훅과 다르게 createStore를 통해

 

store 변수를 가져와 그 안에 reducer 함수를 넣고 사용해야 한다.

 

이제 dispatch 함수를 이용해 state를 바꿔보자.

 

...생략

const store - createStore(reducer)

console.log(store.getState()) // 현재 state 출력

store.dispatch(change_name())
console.log(store.getState())

store.dispatch(order(5))
console.log(store.getState())

결과로 출력되는 객체의 name, coffee의 value가 순서대로 바뀐다면 문제 없이 실행된 것이다.

'React' 카테고리의 다른 글

#17 Router  (0) 2022.05.08
#16 Redux part2  (0) 2022.05.07
#14 useMemo, useCallback  (0) 2022.05.02
#13 useReducer  (0) 2022.05.01
#12 useContext  (0) 2022.04.29