FE/Redux

[Redux toolkit] Redux-thunk를 이용하여 비동기 처리하기

mandelina 2022. 7. 15. 21:09

 

React 프로젝트를 진행 중, 비동기 처리의 결과값을 전역적으로 관리하며 사용해야하는 경우가 생겼다.

그래서 redux-thunk를 도입하게 되었다. redux-thunk에 대해 정리하고, 예제 코드를 살펴보자!

 


 

1. Redux-thunk를 사용하는이유 ?

- 기본 Redux는 간단한 동기적인 처리만 업데이트 할 수 있다.

- 하지만 store에 aceess해야하는 복잡한 동기처리나, AJAX요청과 같은 비동기 처리 같은경우 권장되는 미들웨어이다! 

- Redux 앱에서 비동기 로직을 작성하기 위한 표준 접근 방식이며, 일반적으로 데이터 가져오기에 사용된다. 

 

2. thunk라는 단어의 의미는 ?

- 일부 지연된 작업을 수행하는 코드 조각  을 의미하는 프로그래밍 용어

 

 

Redux-toolkit 개념을 모르신다면 아래의 링크 참고!

https://mandelina-code.tistory.com/99


 

내 프로젝트에서는 Axios요청을 하고, 그 결과값을 여러 컴포넌트에서 사용을 해야하는 상황이였다.

어떻게 처리했는지 예제를 통해 알아보자.

 

실습

1 .  import하기

import {createSlice, createAsyncThunk } from "@reduxjs/toolkit";

 

- Redux-toolkit에는  createAsyncThunk를 사용하는데 이는 redux-thunk 라이브러리를 내장하고 있어서 따로 설치할 필요가 없다.

 

 

2.  getPostSlice.js 

import {createSlice,createAsyncThunk,current } from "@reduxjs/toolkit";
import axios from 'axios';

const initialState = {
  postData: "",
  status : "idle",
}

export const AxiosPost = createAsyncThunk(   // 비동기 버전을 위한 Thunk사용
  'post/axiosPost',    
  async(url) =>{
    console.log(url);
    const token = JSON.parse(localStorage.getItem("token")) ;
    const config = {
      headers: {
        "Authorization" : `Bearer ${token}`,
        "Content-type" : "application/json"
      },
    }
    const res = await axios(url,config);    //비동기 처리
    console.log("res.data.product : ",res.data.product);
    return res.data
  }
)

export const postInfoSlice = createSlice({
  name : "getPost",
  initialState,
  reducers:{
  },
  extraReducers: (builder) => {         //extraReducers에서 프로미스의 상태에 따른 처리를 해준다.
    builder
      .addCase(AxiosPost.pending, (state) => {  //pending일 경우 
        console.log("로드중");
        state.status = 'loading';
      })
      .addCase(AxiosPost.fulfilled, (state, action) => {  // fulfilled일 경우
        console.log("성공",action);
        state.status = 'success';
        state.postData = action.payload;
        console.log(current(state));
      })
      .addCase(AxiosPost.rejected,(state,action) => {  // rejected일 경우
        console.log("실패");
        state.state = 'fail';
      });
  },
})

//stats값을 useSelector로 사용하기 위해 빼놓는다.
// 따로 빼놓는 이유는 무의미한 재렌더링을 막기 위해서이다.

export const selectAllSnsPosts = (state) =>state.getPost.postData;  
export const getSnsPostStatus = (state) => state.getPost.status;
export default  postInfoSlice.reducer;
export const postActions = postInfoSlice.actions;

 

 

3.  Store.js 

import { configureStore  } from "@reduxjs/toolkit";
import getPostReducer from "./reducers/getPostSlice";


export const store = configureStore({   // reducers에서 반환한 새로운 State를  Store객체러 보관
  reducer: {
    getPost: getPostReducer,   //Reducer을 등록해준다.
  },
})

 

4.  API요청을 할 파일에서

import { AxiosPost } from '../../reducers/getPostSlice'

port default function AddSnsPost() { 
 const dispatch = useDispatch();  //dispatch 객체 생성
 .
 .
 .
 //AxiosPost함수를 사용해서 API요청
 dispatch(AxiosPost(URL + ReqPath + "/" + accountname+"/userpost"))  

 .
 .
 .
 
 }

 

dispatch로 Axios요청을 보내고, 이 결과값을 사용하고 싶다면 useSelector를 사용하여 꺼내 사용하면 된다!

 

 

 

 

 

참고문서 

https://redux-toolkit.js.org/api/createAsyncThunk