redux-thunk?
๋ฆฌ๋์ค์ ๊ดํด์ ๊ณต๋ถํ๋ค ๋ณด๋ฉด '๋ฏธ๋ค์จ์ด'๋ผ๋ ๊ฒ์ ํ ๋ฒ์ฏค ๋ค์ด๋ณด์์ ๊ฒ์ด๋ค.
redux-thunk
, redux-saga
, ๊ทธ ์ธ์๋ redux-promise-middleware
๋ฑ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์๋๋ฐ ์ค๋์ ๊ทธ์ค์์๋ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๊ณ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค ํ๋์ธ redux-thunk
์ ๋ํ์ฌ ์ ๋ฆฌํด๋ณด๋ ค ํ๋ค.
๋ฆฌ๋์ค ๋ฏธ๋ค์จ์ด?
๋จผ์ ๋ฏธ๋ค์จ์ด์ ๋ํด์ ์์๋ณผ๊น ํ๋ค.
๋ฆฌ๋์ค๋ฅผ ์ฌ์ฉํด๋ณด์๋ค๋ฉด ์์ ๊ฐ์ ๊ตฌ์กฐ๋ก ๋ฆฌ๋์ค๊ฐ ์๋ก์ด state๋ฅผ ๋ฐํํ๋ค๋ ๊ฒ์ ์๊ณ ์์ ๊ฒ์ด๋ค.
dispatch
๋ฅผ ํตํด ๋ฆฌ๋์๋ก ์ ๋ฌ๋ ์ก์
์ด ๋ฆฌ๋์๋ก ์ ๋ฌ๋์ด state๊ฐ ๋ณ๊ฒฝ๋๋ค๋ ๊ฒ!
๋ฆฌ๋์ค ๋ฏธ๋ค์จ์ด๋ ์ฌ๊ธฐ์ ์ก์ ์ด ๋์คํจ์น๋๊ณ ๋ฆฌ๋์์ ์ ๋ฌ๋๊ธฐ ์ ์ ์ถ๊ฐ์ ์ธ ์์ ์ ์งํํ ์ ์๋ค.
๋ณดํต ์๋ฒ์ ํต์ ํ๋ฉฐ ๋น๋๊ธฐ์์ ์ ์ํด ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
์์ ์ธ๊ธํ ๋ฏธ๋ค์จ์ด๋ค๋ ๋ชจ๋ ๋น๋๊ธฐ ์์ ์ ๊ด๋ จ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด๋ค.
๊ทธ๋ผ ์ด์ ๋ฏธ๋ค์จ์ด๊ฐ ๋ญ์ง ์์์ผ๋ ๊ตฌ์ฒด์ ์ผ๋ก redux-thunk
์ ๋ํด ์์๋ณด์.
redux-thunk
๋น๋๊ธฐ ์์
์ฒ๋ฆฌ์ ๊ฐ์ฅ ๋ง์ด ์ด์ฉํ๋ ๋ฏธ๋ค์จ์ด์ธ thunk์ ๊ฐ์ฅ ํฐ ํน์ง์ ์ก์
๊ฐ์ฒด๊ฐ ์๋, ํจ์๋ฅผ dispatch ํ ์ ์๋ค.
์ฌ๊ธฐ์์ dispatch ํ๋ ํจ์๋ฅผ thunk ํจ์๋ผ๊ณ ํ๋ค.
thunk ํจ์๋ฅผ ์์ฑํ ๋๋ createAsyncThunk
๋ผ๋ ํจ์๋ฅผ ์ด์ฉํ๋ค.
์ด ํจ์์๋ ๋ ๊ฐ์ ์ธ์๊ฐ ๋ค์ด๊ฐ๋๋ฐ, ์ฒซ ๋ฒ์งธ๋ action value, ๋ ๋ฒ์งธ๋ ํจ์๊ฐ ๋ค์ด๊ฐ๋ค. ์ฒ๋ฆฌํด์ผ ํ ์์
์ด ์๋ค๋ฉด ๋ ๋ฒ์งธ ์ธ์์ ํจ์์์ ์์ฑํ๋ฉด ๋๋ค.
์นด์ดํฐ๋ฅผ ์ฆ๊ฐ์ํค๋ ์๋ ํจ์๋ 3์ด ํ์ thunk ํจ์ ๋ด๋ถ์์ dispatch๋ฅผ ์คํํ๋ค.
์ฝ๋๋ฅผ ๋ณด๋ฉด ์๊ฒ ์ง๋ง, ๋ ๋ฒ์งธ ํจ์์์๋ payload์ thunkAPI ์ธ์๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
payload๋ ์ปดํฌ๋ํธ์์ ๋ณด๋ธ payload ์ด๊ณ , thunkAPI๋ thunk๊ฐ ์ ๊ณตํ๋ ์ฌ๋ฌ API๋ฅผ ์ด์ฉํ ์ ์๋ค.
export const __addNumber = createAsyncThunk('addNumber', (payload, thunkAPI) => {
setTimeout(() => {
thunkAPI.dispatch(addNumber(payload));
}, 3000);
});
thunk ํจ์์ ์ฌ์ฉ์ ์ปดํฌ๋ํธ ์์์์ ๊ธฐ๋ณธ ๋ฆฌ๋์์ action creator๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์๊ณผ ๋์ผํ๋ค.
thunk๋ก Promise ํธ๋ค๋ง
thunkAPI๋ฅผ ํตํด์ Promise๋ฅผ ๋ค๋ฃฐ ์ ์๋ค. (Promise๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ๊ฐ์ฒด!)
์์ฒญ์ด ์ฑ๊ณตํ ๊ฒฝ์ฐ dispatch ํ๋ fulfillWithValue
, ์คํจํ์ ๊ฒฝ์ฐ dispatch ํ๋ rejectWithValue
๊ฐ์ API๋ค๋ก thunk ํจ์ ๋ด๋ถ์์ dispatch ํ ์ ์๋ค.
export const __getTodos = createAsyncThunk('todos/getTodos', async (payload, thunkAPI) => {
try {
const data = await axios.get('http://localhost:3001/todos');
return thunkAPI.fulfillWithValue(data.data);
} catch (error) {
return thunkAPI.rejectWithValue(error);
}
});
์ ์ฝ๋๋ง ๋ด์๋ ์ด๋ค ๋ฆฌ๋์์๊ฒ dispatch๋ฅผ ์ ๋ฌํด์ฃผ๋์ง ์ ์ ์๋ค.
๋ฆฌ๋์์ thunk ํจ์๋ฅผ ์ถ๊ฐํ ๋, thunk ํจ์๋ Reducers ์ธ๋ถ์์ ์์ฑ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ extraReducers
๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
์๋์ ์ฝ๋๋ ๋ฐํ๋ Prmomise์ธ ๋ก๋ฉ์ํ(pending, fulfilled, rejected)์ ๋ฐ๋ผ์ ์ํ๋ฅผ ๊ด๋ฆฌํ๊ณ ์๋ค.
์์ thunk ํจ์์์ fulfillWithValue
๋์๋ค๋ฉด extraReducers
์ [__getTodos.fulfilled]
๋ถ๋ถ์ผ๋ก dispatch๊ฐ ์ ๋ฌ๋๋ค.
export const todosSlice = createSlice({
name: 'todos',
initialState,
reducers: {},
extraReducers: {
[__getTodos.pending]: (state) => { // ๋ก๋ฉ์ค์ผ ๋
state.isLoading = true;
},
[__getTodos.fulfilled]: (state, action) => { // ์ฑ๊ณตํ์ ๋
state.isLoading = false;
state.todos = action.payload;
},
[__getTodos.rejected]: (state, action) => { // ์คํจํ์ ๋
state.isLoading = false;
state.error = action.payload;
},
},
});
์ข ๋ ๊ณต๋ถํด๋ด์ผ๊ฒ ์ง๋ง redux-thunk๋ฅผ ์ด์ฉํด์ ๋ฆฌ๋์ค์์์ ๋น๋๊ธฐ ์์ ์ ์ข ๋ ํธํ๊ฒ ์ฒ๋ฆฌํ ์ ์์ ๊ฒ ๊ฐ๋ค!
'๐ Studying > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[React] useRef์ ์ฌ์ฉ ์์ (0) | 2023.04.04 |
---|---|
[React] Styled-Components ํ์ฉ (0) | 2022.12.08 |
[React] State์ Props (0) | 2022.12.07 |
[React] PropTypes๋ก props ํ์ ๊ฒ์ฌ (0) | 2022.12.05 |
[React] ๋ฆฌ๋์ค.. ์ ์ฐ์ฃ ? ํ์์ฑ๊ณผ ๊ทธ ๊ตฌ์กฐ์ ๋ํด (0) | 2022.09.29 |
Comment