[TIL] Redux

김민성·2021년 4월 5일
0
post-thumbnail

Redux

자바스크립트앱에서 예측가능한 상태관리를 해주는 컨테이너

장점

  1. 상태를 예측 가능하게 만들어준다
  2. 유지보수가 용이하다.
  3. 디버깅에 유리하다.
  4. 테스트를 붙이기 쉽다.

-> 자식 컴포넌트끼리 상태를 공유하기 위해서는 부모 컴포넌트를 거쳐야하는데 자식이 많아진다면 부모 컴포넌트를 거치는 과정이 매우 복잡해집니다. 이런 복잡성을 줄이기 위해 Redux를 사용합니다.

Action, Reducer 그리고 Store

store: 상태가 관리되는 오직 하나의 공간을 말합니다.

action: 자바스크립트 객체형태로 스토어에게 데이터를 운반해주는 역할을 한다. action은 action creator 내부에 함수형태로 리턴값을 객체로 받는다.

reducer: action을 통해서 스토어에 데이터를 운반하기 위해서는 거쳐야하는 기능이다.

*사이클: action creator > action > dispatch > reducer > state

액션객체가 디스패치 메소드에 전달이 되고, 디스패치가 리듀서를 호출해서 새로운 스테이트값을 만들어낸다.

Redux의 3가지 원칙

  1. single source of truth
    -> 동일한 데이터는 같은 곳에서 가져온다. store에서 가져온다.
  2. state is read-only
    -> 리덕스에서는 액션이라는 것을 통해서만 상태를 변경할 수 있다.
  3. changes are made with pure functions
    -> 변경은 순수함수로만 가능하다. 리듀서와 연관있다.

Presentational Component / Container Component

(출처: 코드스테이츠)

Presentational Component: 어떻게 보여지는지에 초점을 맞춘 컴포넌트입니다. props를 사용하여 데이터와 함수를 가져와 dom에 관련된 코드를 작성하는 함수라고 생각합니다.

Container Component: 어떻게 동작하는지에 초점을 맞춘 컴포넌트입니다. redux를 사용하여 state를 변경하는 경우가 이에 해당한다고 생각하면 될 것 같습니다.

Pure Redux 작성

코드스테이츠에서 진행하는 스프린트는 아무래도 부분적으로 테스트만 통과하면 되기때문에 상대적으로 이해되는 정도가 떨어졌습니다. 그런데 마침 스프린트 점검 시간에 간단한 redux를 처음부터 짜보는 예시를 보여주셔서 직접 짜면서 과정을 처음부터 이해하려 해보았습니다.

  1. 코드를 저장할 폴더를 만듭니다.
  2. npm init으로 package.json을 만들어 줍니다.
    폴더안에 package.json이 생겼고, 저는 일단 아무 내용도 안적었습니다.(폭풍 엔터)
  3. npm install을 실행한다음 redux도 설치해줍니다. redux는 상태관리 라이브러리이기 때문에 개별적으로도 사용이 가능합니다.
  4. index.js 파일을 만들어서 코드를 작성합니다. 코드를 쓸 때, 제 마음대로 나름의 순서를 정해놓기로 했습니다ㅎㅎ
//1. 스토어 생성을 위해 제일 먼저 작성해줍니다.
const { createStore } = require('redux')

//2. 초기 state를 정의합니다.
const initState = {
    name: '김개발',
    post: []
}

//action
//3. action creator 함수 작성. 리턴 값은 객체로 작성해줍니다.
const changeUsername = (data) => {
    return {
        type: 'CHANGE_NAME',
        data
    }
}

const addPost = (post) => {
    return {
        type: 'ADD_POST',
        post
    }
}

//4. reducer
//action 의 타입에 따라서 새로운 state를 생성해내는 순수 함수
const reducer = (prevState, action) => {

    switch(action.type){
        case 'CHANGE_NAME':
            return {
                ...prevState,
                name: action.data
            }
        case 'ADD_POST': 
            return {
                ...prevState,
                post: [...prevState.post, action.post]
            }
        default:
            return prevState
    }
}

//5. store를 선언해줍니다. createStore에는 첫 번째 인자로 reducer, 두 번째 인자로initState, 초기값이 들어갑니다.
const store = createStore(reducer, initState)

//6. dispatch 작성. store에서 정보를 가져와 action 객체를 dispatch로 실행하면 리듀서에서 상태를 바꾸어 줍니다.
store.dispatch(changeUsername('이름변경'))
store.dispatch(addPost('post 1'))
//store.getState()로 상태변화를 파악할 수 있습니다.
console.log(store.getState())

redux-thunk

redux-thunk는 redux에서 동기적으로 실행되는 dispatch를 활용하여 비동기적으로 보이게 만들어줍니다. 액션 생산자 안에서 dispatch를 실행하고 setTimeout를 활용하여 함수를 dispatch로 실행시켜 준다면 비동기 액션이 발생하게 만들 수 있습니다. 중요한 것은 비동기 액션은 상태 변경이 일어나는 동기 액션으로 구분지어 생각해야 한다는 점입니다.

const example = () => {
	dispatch(func());
	setTimeout(() => {
		dispatch(anotherFunc())
	}, time)
}

위와 같이 func()를 실행하고 time 시간뒤에 anotherFunc()가 실행되는 비동기적 액션을 구현할 수 있는데 이것이 redux-thunk입니다.

정신없이 블로깅을 하고 있는데 정리가 잘 되는지 모르겠습니다. 주말을 이용해서 직접 코드를 작성해가면서 익숙해지도록 해야겠습니다.

profile
https://github.com/alstjd8826

0개의 댓글