물론 다 그런 건 아니지만 만약 500에러가 뜨면 변수명이나 key값이 동일한지, 올바른 key값을 적었는지 확인하기. 500에러 뜰리가 없는데 떠서 '왜지..'했는데 props로 불러오는 key값을 잘못 적었다ㅎㅎ (엣큥-!)
export default function* Saga{
return(
)
}
thunk는 예를들어 setTimeout()을 직접 하나하나 적어야 하는 부분이 있지만, saga는 이미 이런 이벤트들이 만들어져있다. (편하다는 소리)
yield
를 중간에 중단시점을 지정한 곳에 넣으면 함수가 중단이 된다.2. 절대 중단하지 않는 함수
```javascript
const gen = function*() {
while(true){
yield '무한';
}
}
```
yield
를 적으면 무한반복되지 않고 중단이 된다!!
yield를 붙이는 이유 중 하나는 테스트하기가 정말 편안하기 때문이다.
왜냐하면 yield를 넣으면 한줄한줄 멈춤으로 한줄한줄 잘 작동하는지 확인을 할 수 있기 때문이다.
ex. 버튼을 누를 때 특정 이벤트를 활성하도록!!
function* watchLogIn() {
yield take('LOG_IN') // 해석 : 'LOG_IN'이라는 액션을 실행될 때까지 기대리겠다.
}
그리고
3. function logInAPI() {
// [주의] 이 함수는 *(generator)를 붙이지 않는다.
return axios.post('/api/login')
}
2. function* logIn() {
try{
const result = yield call(logInAPI) // logInAPI 요청 결과 담기
yield put({
type : 'LOG_IN_SUCCESS',
data : result.data
})
} catch (err) {
yield put({
type: 'LOG_IN_FAILURE',
data: err.response.data
})
}
}
1. function* watchLogIn() {
yield take('LOG_IN', logIn)
// 해석 : "'LOG_IN'이라는 액션이 실행되면, logIn 함수를 실행하겠다" 라는 뜻.
}
saga effects
take effects는 일회성이다.
즉 한번 로그인->로그아웃하고 다시 로그인하려고 하면 안된다. 한번만 로그인 하고 끝이난다. 이를 해결하기 위해서 while!!
while, take는 동기적으로 동작하지만, takeEvery는 비동기로 동작한다는 차이가 있다.
1. function* watchLogIn() {
while(true){
yield takeEvery('LOG_IN_REQUEST', logIn)
}
}
2. function* watchLogIn() {
yield takeEvery('LOG_IN_REQUEST', logIn)
}
1번 while문으로 쓴 것은 약간 직관적이지 않는다. 2번은 takeEvery는 길이도 짧아지고 좀더 직관적으로 간결하게 사용할 수 있다.
하지만 takeEvery
를 사용한다면,
만약 클릭을 연속 3번을 눌렀다고 하면 3번 다 요청이 들어간다. 이를 방지하기 위해서 takeLastest
를 사용하면 된다. 그렇다면 99번 눌러도 나머지 98번은 무시되고 마지막 99번째 딱 한번만 요청이 들어가게된다.
(사용예제)
function* watchLogIn() {
yield takeLastest('LOG_IN_REQUEST', logIn)
}
여기에도 치명적인 단점이 있다.
응답을 취소하는 거지 요청을 취소하지 않는 것.
즉 서버쪽에서는 요청을 2번 받는 것이다.
프론트 쪽에서는 단 하나의 응답만 받지만 백엔드는 요청 2개를 받는다.
그래서 takeLastest
만으로는 안되고, Throttle
를 사용한다.
function* watchLogIn() {
yield throttle('LOG_IN_REQUEST', logIn, 2000)
}
'2초동안 logIn 요청을 한번만 할 수 있도록 한 것'
'2초동안 100번을 연속해서 눌러도 한번만 요청이 들어간다.'
fork와 call의 차이점
fork는 비동기 함수 호출 , call은 동기 함수 호출이다.