바로 Redux의 비동기 처리를 위함이다!
import {createStore} from 'redux';
import {Provider, useSelector, useDispatch } from 'react-redux';
function reducer(currentState, action) {
if (currentState === undefined) {
return {
number: 1,
};
}
const newState = {...currentState};
if (action.type === "PLUS") {
newState.number ++;
}
return new State
}
const store = createStore(reducer);
새로운 component
function Left3() {
const dispatch = useDispatch();
const number = useSelector((state) => state.number);
return (
<div>number</div>
<input onClick = {() => { dispatch({type: "PLUS"});} ></input> // dispatch 가 일어나면 reducer가 호출된다.
);
}
코드가 간단하다.
하지만 다양한 기능을 가지고 있지 않는다.(delay 기능)
export const loginAction = (data) => {
return (dispatch, getState) => {
const state = getState();
dispatch(loginRequestAction());
axios.post('/api/login')
.then(()=> {
dispatch(loginSuccessAction());
})
.catch(() => {
dispatch(loginFailureAction());
})
}
}
export const loginRequestAction = (data) => {
return {
type: 'LOG_IN_RQUEST',
data,
}
};
실수로 클릭을 두번하거나, thunk 2번의 클릭에 요청이 모두 간다.
하지만 saga의 경우는 마지막 경우만 진행
스크롤 이벤트를 1초에 수백번 일어난다.
하지만, 그때 비동기 통신을 걸어두면 서버에 요청이 수백개 날아간다.
이때 DDOS 공격이 생길 수 있다.
프론트 실력과 연관될 수 있다.
어려운 이유는 제너레이터를 사용하기 때문이다.
const gen = function* () {
console.log(1);
yield;
console.log(2);
yield;
console.log(3);
yield;
}
const generate = gen();
generate.next()
//1
generate.next()
//2
generate.next()
//3
제너레이터는 yield를 기준으로 중단점이 있는 함수이다.
export default function* rootSaga() {
}
루트 사가를 만든 후 그 곳에 만들고 싶은 비동기 action을 만들어 준다.
import { all, fork, take, call, put } from "redux-saga/effects";
import axios from "axios";
function logInAPI() {
return axios.post("/api/login");
}
// 서버에게 요청하는 함수인 login 함수 실
function* logIn() {
try {
const result = yield call(logInAPI);
yield put({
type: "LOG_IN_SUCEESS",
data: result.data,
});
} catch (err) {
yield put({
type: "LOG_IN_FAILURE",
data: err.response.data,
});
}
}
//"LOG_IN"이라는 액션이 실행될 때까지 기다리겠다. 이후 로그인 제너레이처 함수를 실행를 실행 시키겠다.
// 이벤트 리슨어 처럼 실행된다.
function* watchLogin() {
yield take("LOG_IN_REQUEST", login);
}
// rootsaga
// watchLogin fork 실행 watchLogout fork 실행
// event listener 등록
export default function* rootSaga() {
yield all([fork(watchLogin), fork(watchLogout), fork(watchAddpost)]);
}
call과 fork의 차이
단순 프로그램을 동작하기 위함이 아니다.
동작이 제대로 돌아가고 있는지 보장을 받는게 중요하다.
때문에 effect를 사용해서 테스트를 사용하면 프로그램 동작을 확인하기가 쉽다.