생활코딩의 redux toolkit - thunk 를 이용해서 비동기 작업을 처리하는 방법을 듣고 정리한 내용입니다.
서버와 통신하는 경우처럼 redux로 비동기 작업을 어떻게 처리해야 할까?
createAsynkThunk
- 비동기 작업을 처리하는 action을 만들어준다.
- 인자로 타입(string)과 promise를 반환하는 함수, 옵션을 받는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// counterSlice.js
const asynkUpFetch = createAsynkThunk("counterSlice/asyncUpFetch", async () => {
const resp = await fetch(url);
const data = await resp.json();
// 여기서 return한 value는 payload로 reducer에 전달된다.
return data.value;
});
// 다른 파일에서
<button
onClick={() => {
dispatch(asyncUpFetch());
}}
>
+ async fetch
</button>;
extraReducers
createAsyncThunk를 썼을 때 action creator가 같는 3가지 상태가 있다.
pending : 대기 상태
fulfilled : 완료 상태
rejected : 오류 상태
- reducer는 createSlice 안에 extraReducers로 정의한다.
- 이때 builder.addCase()를 사용한다.
(fulfilled일 때만 정의해도 된다.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const counterSlice = createSlice({
name: "counterSlice",
initialState: {
value: 0,
status: "Welcome"
},
reducers: {
up: (state, action) => {
state.value = state.value + action.payload;
}
},
// 여기!
extraReducers: (builder) => {
// pending 상태일 때 reducer를 두 번째 인자로 전달한다.
builder.addCase(asyncUpFetch.pending, (state, action) => {
// 여기서 작성한 status는 useSelector의 status로 전달된다.
state.status = "Loading";
});
// fulfilled 상태일 때 reducer를 두 번째 인자로 전달한다.
builder.addCase(asyncUpFetch.fulfilled, (state, action) => {
// 여기서 작성한 value는 useSelector의 value로 전달된다.
state.value = action.payload;
state.status = "complete";
});
// rejected 상태일 때 reducer를 두 번째 인자로 전달한다.
builder.addCase(asyncUpFetch.rejected, (state, action) => {
state.status = "fail";
});
}
});
왜 비동기 작업은 extraReducers로 reducer를 따로 만들까?
- reducers를 사용하면
action creator
를 toolkit이 자동으로 만들어주지만, 비동기 작업에서는 그렇지 않기 때문이다. 그렇기 때문에 extraReducers 내부에 action creator를 정의한다.
출처) 생활코딩 : redux toolkit - thunk 를 이용해서 비동기 작업을 처리하는 방법