TIL 9주차 Redux Thunk

lim1313·2021년 9월 17일
0

부트캠프 TIL

목록 보기
32/49

Redux

📌리덕스의 3가지 규칙

  1. 하나의 애플리케이션 안에는 하나의 스토어
  2. 상태는 읽기 전용
    : 불변성을 유지해야 하는 이유는 내부적으로 데이터가 변경 되는 것을 감지하기 위하여 shallow equality 검사를 하기 때문
  3. 변화를 일으키는 함수, 리듀서는 순수한 함수여야 한다.
    : 리듀서 함수는 이전 상태와, 액션 객체를 파라미터로 받습니다.
    : 이전의 상태는 절대로 건들이지 않고, 변화를 일으킨 새로운 상태 객체를 만들어서 반환합니다.
    : 똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결과값을 반환해야만 합니다.

동일한 인풋이라면 언제나 동일한 아웃풋이 있어야 한다.

일부 로직들 중에서는 실행 할 때마다 다른 결과값이 나타날 수도 있다. new Date(), 랜덤 숫자 생성, 혹은, 네트워크에 요청 등등.
그러한 작업은 결코 순수하지 않은 작업이므로, 리듀서 함수의 바깥에서 처리해줘야 한다. 이를 위해, 리덕스 미들웨어 를 사용하곤 한다.

📌리덕스 사용 준비

npx create-react-app practice-redux
npm install redux react-redux

📌리덕스 사용 정리

리덕스 사용 정리
Redux의 구성 요소
Redux 사용
Redux 모듈화


미들웨어

rootReducer.js

import { combineReducers } from 'redux';
import subscriberReducer from './subscribers/reducer';
import viewsReducer from './views/reducer';

const rootReducer = combineReducers({
  view: viewsReducer,
  subscribers: subscriberReducer,
});

export default rootReducer;

📌logger

npm install redux-logger
import { createStore, applyMiddleware } from 'redux';
import rootReducer from './rootReducer';
import { composeWithDevTools } from 'redux-devtools-extension';

// 미들웨어 logger
import logger from 'redux-logger';
import subscriberReducer from './subscribers/reducer';

// 미들웨어가 여러개일 때 배열에 넣어서 사용
const middleware = [logger];

// 두개의 reducer를 하나의 store로
// 미들웨어는 두번째 인자에
const store = createStore(
  rootReducer,
  composeWithDevTools(applyMiddleware(...middleware))
);

export default store;

📌redux-thunk

리덕스에서 비동기 작업을 처리할 때는 redux-thunk라는 미들웨어를 많이 사용한다.
thunk 미들웨어는 객체 대신 함수를 생성하는 액션 생성함수를 작성 할 수 있도록 해준다.

npm install redux-thunk

비동기 액션 생산자는 리듀서로 연결되지 않고, 직접 dispatcher를 통해 스토어로 새로운 상태를 보내준다. 함수를 dispatch 할 때에는, 해당 함수에서 dispatch 와 getState 를 파라미터로 받아와주어야 한다.

thunk를 middleware에 추가해주면, action에서 dispatch를 리턴해 줄 수 있는 기능 사용이 가능해진다.

1. 아래와 같이 thunk를 store의 미들웨어에 추가해준다.

import { createStore, applyMiddleware } from 'redux';
import rootReducer from './rootReducer';
import { composeWithDevTools } from 'redux-devtools-extension';

import thunk from 'redux-thunk';

import logger from 'redux-logger';
import subscriberReducer from './subscribers/reducer';

const middleware = [logger, thunk];

const store = createStore(
  rootReducer,
  composeWithDevTools(applyMiddleware(...middleware))
);

export default store;

2. 함수를 dispatch할 때, dispatch와 getState를 인자로 넣어준다.

export const addSubscriber = () => {
  return (dispatch, getState) => {
    console.log(getState()); //-> {view: {…}, subscribers: {…}}
    setTimeout(() => {
      dispatch({ type: ADD_SUBSCRIBER });
    }, 1000); // 1초 후에 dispatch 실행 
  };
};

3. 비동기적으로 실행되기를 원하는 이벤트의 dispatch에 action을 넣어준다.

 <button onClick={() => dispatch(addSubscriber())}>구독</button>


action 함수에서 dispatch, getState 를 파라미터로 받게 한다면 스토어의 상태에 접근할 수 있다.
따라서, 현재의 스토어 상태의 값에 따라 액션이 dispatch 할지, 안할지를 결정할 수 있다.

즉, redux-thunk 는 일반 액션 생성자에 날개를 달아준다. 보통의 액션생성자는 그냥 하나의 액션객체를 생성 할 뿐이지만, redux-thunk 를 통해 만든 액션생성자는 그 내부에서 여러가지 작업을 할 수 있다. 이 곳에서 네트워크 요청도 할 수 있고, 여러번의 디스패치를 할 수도 있다.


Redux devtools extenstion

redux devtool 설명

npm install --save redux-devtools-extension
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';

const middleware = [thunk];

const store = createStore(reducer, composeWithDevTools(
  applyMiddleware(...middleware),
  // other store enhancers if any
));

참고) react redux 정리 블로그
참고) code scalper 유튜브 redux 강의

profile
start coding

0개의 댓글