redux-thunk

김태완·2022년 1월 2일
0

React

목록 보기
8/24
post-thumbnail

redux는 동기적으로 작업하기때문에 비동기작업엔 추가적인 미들웨어가 필요하다,
대표적으로 thunk와 saga가 있는데 비교적 난이도가 쉬운 thunk부터 정리해보자

react컴포넌트는 상태에 따른 화면을 정의하는것이 기본 목적이다.
redux만 사용해서는 비즈니스로직이 컴포넌트내에 섞이는등의 단점이 생기기때문에 이를 해결하기위해 미들웨어가 사용된다

redux의 한계

  • 전역에서 상태값을 관리가능
  • redux를 쓰면 리액트컴포넌트와 상태값을 따로 관리가능!
  • 하지만, redux는 액션으로 상태값의 변화에만 관심이 있고 중간과정에는 관심이 없다(제어가 안된다). 따라서 아래 2개의 미들웨어를 추가로 사용한다

redux-thunk 장점

  • redux-thunk를 사용하면 액션이 아닌 함수를 전달하여 비동기작업까지 처리가 가능하다.

redux-thunk를 사용하기위해 redux 디렉터리를 추가한뒤 그 아래 actions, reducer폴더와 store.js를 생성해준다.

redux-thunk 사용법

  1. 우선 redux/reducer에 reducer.js파일을 생성해주고 초기값설정, 리듀서생성을 해준다
  • 여기서 action.payload로 데이터를 받아 상태값에 불변성을 지켜서 대입해준다
//redux/reducer/reducer.js

import { INCREMENT, FETCH_DATA } from "../actions/actions";

const INITIAL_STATE = {
  count: 1,
  datas: [],
};

export default function counter(state = INITIAL_STATE, action) {
  switch (action.type) {
    case INCREMENT:
      return {
        ...state,
        count: state.count + 1,
      };
    case FETCH_DATA:
      return {
        ...state,
        datas: action.payload,
      };

    default:
      return state;
  }
}
  1. redux/reducer에 index.js파일을 생성해서 리듀서들을 합쳐준다 (예제는 리듀서가 1개임)
// redux/reducer/index.js

import { combineReducers } from "redux";
import counter from "./reducer";

const rootReducer = combineReducers({ counter });

export default rootReducer;
  1. redux/actions에 action.js파일을 생성해서 액션과 액션이벤트를 만들어준다
  • 예제에는 동기적 dispatch 1개와 비동기 dispatch 2개(1초뒤 count up, fetchData)를 예시로 들었다
import axios from "axios";

// 액션 추가
export const INCREMENT = "INCREMENT";
export const INCREASE_ASYNC = "INCREASE_ASYNC";
export const FETCH_DATA = "FETCH_DATA";

export const increment = () => ({ type: INCREMENT });
export const incrementAsync = () => ({ type: INCREASE_ASYNC });
export const fetchData = (data) => ({ type: FETCH_DATA, payload: data });

// 액션 함수선언 (실제 페이지들에서 사용될 액션함수)
export const increaseAsync = () => (dispatch) => {
  setTimeout(() => dispatch(increment()), 1000);
};

export const fetchDataAsync = () => (dispatch) => {
  const fetchFun = async () => {
    const res = await axios.get("https://jsonplaceholder.typicode.com/posts");
    dispatch(fetchData(res.data));
  };
  fetchFun();
};
  1. redux에 store.js를 생성해서 생성한 리듀서를 넘겨준다
// redux/store.js

import rootReducer from "./reducer/index";
import { createStore, applyMiddleware } from "redux";
import logger from "redux-logger";
import { composeWithDevTools } from "redux-devtools-extension";
import ReduxThunk from "redux-thunk";

export const store = createStore(
  rootReducer,
  composeWithDevTools(applyMiddleware(ReduxThunk, logger))
);
  1. 마지막으로 최상위 index.js에서 App컴포넌트를 Provider로 감싸주고 store값을 props로 넘겨준다
// index.js
import { Provider } from "react-redux";
import { store } from "./redux/store";

ReactDOM.render(
  <Provider store={store}>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </Provider>,

  document.getElementById("root")
);
profile
프론트엔드개발

0개의 댓글