https://react.vlpt.us/redux-middleware/04-redux-thunk.html
공식문서에 따르면 리덕스에서 비동기 작업을 처리하기 위해 사용하는 미들웨어이다.
이를 사용하면 액션 객체가 아닌 함수를 디스패치할 수 있다.
npm install redux-thunk
createAsyncThunk( action.type , action creator 가 실제로 실행될 코드 = store에 state를 변경해주는 reducer )
동기적인 액션을 할 경우에는 reducers를, 비동기적인 액션에는 extraReducers 를 사용한다.
reducers로 동기작업을 할 때는 redux-toolkit 이 action creator 를 자동으로 만들어주지만, extraReducers 는 자동으로 생성하지 못해 안에서 직접 만들어준다.
extraReducers
는 세가지 case를 가진다.store 와 관련된 작업 끝
action creator 호출
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 };
import { configureStore } from "@reduxjs/toolkit";
import counterSlice from "./counterSlice";
const store = configureStore({
reducer: {counter: counterSlice.reducer}
});
export default store;
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())
따른 코드 진행은 다음과 같다.