๐ฅ redux-saga
- ๋น๋๊ธฐ ์์ ์ ํ๋ ๋ฏธ๋ค์จ์ด๊ฐ ํ์ํ ๋ ์ฌ์ฉํ๋ค.
- ํน์ ์ก์ ์ด ๋ฐ์ํ์ ๋ ์ํ ๊ฐ์ด๋ ์๋ต ์ํ ๋ฑ์ ๋ฐ๋ผ ๋ค๋ฅธ ์ก์ ์ ๋์คํจ์น ํ๊ฑฐ๋ ์ถ๊ฐ์ ์ธ ๋ก์ง์ ์ ์ฉ ํด์ผ๋ ๋ ์ฌ์ฉํ ์ ์๋ค.
- api์์ฒญ, ์์ฒญ ์คํจ ์ ์ฌ์์ฒญ ๋ฑ์ ๋ฆฌ๋์ค์ ๊ด๊ณ์๋ ์ฝ๋๋ฅผ ๋ฏธ๋ค์จ์ด๋ก ์คํ์ํฌ ์ ์๋ค.
yarn add redux-saga ๋๋ npm install redux-saga
โ generator ํจ์
- generator ํจ์๋ ์ผ๋ฐ ํจ์์๋ ๋ค๋ฅด๊ฒ ํจ์ ์ฝ๋ ์คํ์ ์ผ์ ์ค์งํ๋ค๊ฐ ํ์ํ ์์ ์ ์ฌ์์ํ ์ ์๋ ํจ์์ด๋ค.
- yield๋ ์ค๋จ์ ์ ๋ง๋ ๋ค.
- yield ๋ค์ ๊ฐ์ด ์์ผ๋ฉด ๊ทธ๊ฑธ ๊ฐ์ฒด์ value์ ๋ด์ returnํ๊ณ ๋ฉ์ถ๋ค.
- ์๋์ ๊ฐ์ด function*๋ก ์ ์ธํ๋ค.
- next()๋ฅผ ํตํด์ ๋ค์ ์ค๋จ์ ๊น์ง ์คํ์ํฌ ์ ์๋ค.
โ ์์ฃผ ์ฐ์ด๋ effects
import {all, fork, take, call, put} from 'redux-saga/effects';
import {all, fork, take, call, put} from 'redux-saga/effects';
- effect๋ yield๋ค์ ์ค๋ ํจ์๋ก, ๊ฐ์์ ์ญํ ์ ์ํํ๋ค.
- take
ํด๋น ์ก์ ์ด dispatch๋๋ฉด ์ ๋๋ ์ดํฐ๋ฅผ nextํ๋ค.
function* watchLogIn() {
yield take('LOG_IN', logIn); // 'LOG_IN'์ด ๋ค์ด์ค๋ฉด logIn ํจ์ ์คํ
}
- put
ํน์ action์ dispatch ์์ผ์ค๋ค.
ํ๋ผ๋ฏธํฐ๋ก๋ ์ก์ ๊ฐ์ฒด๊ฐ ๋ค์ด๊ฐ๋ค.
yield put({
type: 'LOG_IN_SUCCESS',
data: result.data
});
- takeEvery
๋ชจ๋ ํด๋น ์ก์ ์ ์ฒ๋ฆฌํ๋ค. - takeLatest
๊ฐ์ฅ ๋ง์ง๋ง์ผ๋ก dispatch๋ ์ก์ ์ ์ฒ๋ฆฌํ๋ค. - all
์ฌ๋ฌ ์ฌ๊ฐ๋ฅผ ํฉ์ณ์ฃผ๋ ์ญํ ์ ํ๋ค. all์ ํ๋ผ๋ฏธํฐ๋ก ๋ฐฐ์ด์ ๋ฐ๋๋ฐ, ๋ฐฐ์ด ๋ด์ ์๋ ๊ฒ์ ๋ชจ๋ ์คํ์ํจ๋ค. - call
ํจ์๋ฅผ ๋๊ธฐ์ ์ผ๋ก ์คํ์์ผ์ค๋ค. ์ฒซ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ ํจ์, ๋๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ ํด๋น ํจ์์ ๋ฃ์ ์ธ์์ด๋ค.
yield call(request, action.payload)
- fork
call๊ณผ ํ๋ผ๋ฏธํฐ๊ฐ ๊ฐ๊ณ ๋ง์ฐฌ๊ฐ์ง๋ก ํจ์๋ฅผ ์คํ์ํค๋ ์ญํ ์ด๋ค. ๊ทธ๋ฌ๋ ๋น๋๊ธฐ์ด๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ณผ๊ฐ์ ๊ธฐ๋ค๋ ค ์ฃผ์ง ์๋๋ค.
export default function* rootSaga() {
yield all([
fork(ํจ์),
fork(ํจ์)
])
}
๐ฅ ๊ธฐ์ด ๊ตฌํ ์ฝ๋
import {all, fork, take, call, put} from 'redux-saga/effects';
import axios from 'axios';
function logInAPI(data) {
return axios.post('url/api/login', data);
}
function* logIn(action) {
try {
const result = yield call(logInAPI, action.data);
// logInAPI์ ์ ๋ฌํ ํ๋ผ๋ฏธํฐ๋ฅผ call์ ๋๋ฒ์งธ ํ๋ฆฌ๋ฏธํฐ๋ก ์ง์ ํด์ค๋ค.
// action์ด login์ ๋ํ ์ก์
์ด๋๊น action.data์ ๋ด๊ฐ ๋ฃ์ด๋ ๋ฐ์ดํฐ๊ฐ ๋ค์ด์๋ค.
yield put({
type: 'LOG_IN_SUCCESS',
data: result.data
});
} catch (err) {
yield put({
type: 'LOG_IN_FAILURE',
data: err.response.data
});
}
}
function* watchLogIn() {
yield take('LOG_IN', logIn); // login์ ๋ํ ์ก์
์์ฒด๊ฐ logIn์ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฌ๋๋ค.
}
// (a) ์ก์
์ ๋ฐ์์ํค๊ณ ์ถ์ ์์ ์์ ์๋์ ๊ฐ์ด dispatch!
dispatch(login({data: user}));
- ์๋ฅผ ๋ค์ด ๋ด๊ฐ LOG_IN ์ก์ ์ ๋ํ ์ก์ ์์ฑํจ์๋ฅผ login์ผ๋ก ๋ง๋ค์์ ๋
- ํด๋น ์ก์ ์ ๋ฐ์์ํค๊ณ ์ถ์ ์์ ์์ (a) ๊ฐ์ด dispatchํ๋ฉด
- watchLogInํจ์ ๋ด์ take์์ ๋ฐ์์ logIn generatorํจ์๋ฅผ ์คํ์ํจ๋ค.
- ์ด๋, logIn์ ํ๋ผ๋ฏธํฐ action์ผ๋ก๋ ๋ด๊ฐ dispatchํ ์ก์ ์์ฒด๊ฐ ๋ค์ด์จ๋ค. (์ฆ action.data๋ ๋ด๊ฐ ๋ฃ์ user)
- ๊ทธ ๊ฐ์ผ๋ก axios์์ฒญ์ ํ๊ณ ์ฑ๊ณตํ๋ฉด LOG_IN_SUCCESS put
- ์คํจํ๋ฉด LOG_IN_FAILURE์ putํ๋ค.
- ๊ฐ๊ฐ LOG_IN_SUCCESS์ LOG_IN_FAILURE์ ๋ํด์ ์ฑ๊ณต ์ state๋ฅผ ๋ฐ๊พธ๋ ๋ฑ์ ์ฝ๋๋ฅผ ๋ฆฌ๋์๋ก ์์ฑํด์ผ ํ๋ค.
๋ฐ์ํ
'react > redux' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[React] redux-actions๋ก ๊ฐ๋ ์ฑ ๋์ด๊ธฐ (0) | 2021.03.31 |
---|---|
[React] useSelector, useDispatch๋ก state์ ์ ๊ทผํ๊ธฐ (0) | 2021.03.31 |
[React] ๋ฆฌ๋์ค ์์ํ๊ธฐ (redux, react-redux) (0) | 2021.03.31 |