Redux toolkit - thunk

jeongjwon·2023년 5월 27일
0

SEB FE

목록 보기
51/56

Redux-thunk

https://react.vlpt.us/redux-middleware/04-redux-thunk.html

공식문서에 따르면 리덕스에서 비동기 작업을 처리하기 위해 사용하는 미들웨어이다.
이를 사용하면 액션 객체가 아닌 함수를 디스패치할 수 있다.

설치하기

npm install redux-thunk

카운터 적용하기

  • createAsyncThunk( action.type , action creator 가 실제로 실행될 코드 = store에 state를 변경해주는 reducer )
    비동기 작업을 처리하는 action creator 를 만든다.

동기적인 액션을 할 경우에는 reducers를, 비동기적인 액션에는 extraReducers 를 사용한다.
reducers로 동기작업을 할 때는 redux-toolkit 이 action creator 를 자동으로 만들어주지만, extraReducers 는 자동으로 생성하지 못해 안에서 직접 만들어준다.

  • extraReducers 는 세가지 case를 가진다.
    actor creator.pending : 대기 상태
    actor creator.fulfilled : 완료 상태
    actor creator.rejected : 오류 상태

store 와 관련된 작업 끝

action creator 호출

counterSlice.js

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

const asyncUpFetch = createAsyncThunk(
  'counterSlice/asyncUpFetch', 
  async () => {
  	const res = await fetch('...');
    const data = res.json();
    return data.value;
  });

const counterSlice = createSlice({
	name: 'counterSlice',
  	initialState: {
      value: 0,
      status: 'Welcome',
    }, 
  reducers: {
  	up: (state, action) => {
    	state.value = state.value + action.payload;
    }
  },
  extraReducers: (builder) => {
  	builder.addCase(asyncUpFetch.pending, (state, action) => {
      //대기상태일 때
    	state.status = 'Loading';
    });
    builder.addCase(asyncUpFetch.fulfilled, (state, action) => {
      //성공했을 때
    	state.status = 'Success';
      	state.value = action.payload;
    });
    builder.addCase(asyncUpFetch.rejected, (state, action) => {
    	//실패했을 때
      	state.status = 'Fail';
    });               
  }
});

export default counterSlice;
export const { up } = counterSlice.actions;
export { asyncUpFetch };

store.js

import { configureStore } from "@reduxjs/toolkit";
import counterSlice from "./counterSlice";

const store = configureStore({
	reducer: {counter: counterSlice.reducer}
});
export default store;

Counter.js

import { useSelector, useDispatch } from "react-redux";
import { up, asyncUpFetch } from "./counterSlice";

function Counter() {
	const count = useSelector(state => state.counter.value);
  	const status = useSelector(state => state.counter.status);
  	const dispatch = useDispatch();
  
  return(
  	<div>
    	//2씩 증가 시키는 버튼
    	<button onClick={() => dispatch(up(2))}>+</button>
		//서버에서 받아온 value 값으로 변경시키는 버튼
		<button onClick={() => dispatch(asyncUpFetch())}>+ async fetch</button>	
		<br />
         
        <div>{count} | {status}</div>
    </div>
    
  )

}


dispatch(asyncUpFetch()) 따른 코드 진행은 다음과 같다.

0개의 댓글