일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- 프로그래밍
- JavaScript
- nodejs
- 주짓떼라
- 영화감상
- graphQL
- 드릴
- Express
- 디자인패턴
- 자바스크립트
- 웹개발
- REACT
- development
- 솔로드릴
- 파이썬
- 주짓떼로
- Redux
- 하프가드
- git
- 클로즈가드
- 리액트
- 영화리뷰
- 노드
- 개발자
- 엄티로드
- 개발
- 영화
- 주짓수
- Node
- web
- Today
- Total
As i wish
[React SNS] React SNS 만들기 - 4 - 1 (redux saga 란, airbnbStyle applied) 본문
[React SNS] React SNS 만들기 - 4 - 1 (redux saga 란, airbnbStyle applied)
어면태 2019. 8. 12. 12:26안녕하세요. 엄티입니다.
계속해서 React 를 사용해서 SNS 를 만들어 보겠습니다.
프로젝트 소개와 프로젝트 구성 요소는 제 전 포스팅을 참고해주세요.
참고로 제 포스팅은 '제로초' 님의 SNS 만들기 강좌 복습 포스팅입니다.
4강에서는 redux-saga 를 적용하였습니다.
redux에 action 은 동기적이기 때문에 비동기적인 일들을 처리하기 위해서는 미들웨어가 필요한데
그 중에 redux-saga 를 선택해서 적용하였습니다.
유명한 미들웨어로는 redux-thunk, redux-saga, mobx 등이 있습니다.
저는 처음에는 redux-thunk 를 사용하다가 요즘에는 redux-saga 를 많이 사용하게 되었는데요,
두개의 차이는 redux-thunk 는 action 생성자를 변형해서 action 생성자 안에서 여러가지 로직을 한 후 새로운 action 생성자를 dispatch 해주게 되죠.
그에 반에 redux-saga 는 action 생성자를 변형하지 않고 action 생성자는 action 생성자만의 역할을 하게 되죠 (type, payload, error 등을 return) 그리고 saga 가 dispatch된 action type 을 바탕으로 그에 맞는 새로운 로직들을 진행하게 되죠.
이러한 점이 두개의 차이점인데 redux-thunk 같은 경우는 redux-saga 보다 러닝커브가 낮고 배우기도 쉽습니다. 사실 redux-saga 에서 할 수 있는 것들을 대부분 redux-thunk 로 할 수도 있는데요. 그럼에도 redux-saga를 사용하는 이유는 (제 이유 입니다!) action 생성자들안에서 일어날 수 있는 side-effect 를 최소화 시킨다고 생각해요. action생성자라고 하면 간단하게 type, payload 를 return 하는게 일반적이라고 생각하는데 redux-thunk를 사용하면 이게 벗어나기 때문이죠. 지극히 저의 주관적인 생각입니다!
무튼 이렇게 redux-saga 를 적용해 보겠습니다.
제가 간단하게 redux-saga에 동작에 대하여 프로젝트를 만들었는데, 한번 확인해 보겠습니다.
component 에서 특정 action 을 dispatch 하면 미들웨어인 saga 가 이를 캐치 해서 원하는 일들을 해주는데요.
import { all, put, take, select, delay, takeLatest, takeEvery, call, fork } from 'redux-saga/effects';
import * as actions from './actions';
function _login() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 3000)
});
}
function* loginAction() {
try {
yield call(_login);
yield put({
type: actions.LOGIN_SUCCESS
})
} catch(error) {
console.log("Login error", error);
yield put({
type: actions.LOGIN_FAILURE
})
}
}
// function* actionWatcher() {
// while(true) {
// yield take(actions.LOGIN_REQUEST);
// yield call(loginAction);
// }
// }
function* actionWatcher() {
yield takeEvery(actions.LOGIN_REQUEST, loginAction);
// yield takeLatest(actions.LOGIN_REQUEST, loginAction);
}
export default function* rootSaga() {
yield all([
fork(actionWatcher),
]);
}
이것이 saga 입니다. 가장 밑에 rootSaga 가 all 를 통하여 watcher 들을 등록시켜주고 있고요, watcher 들은 takeEvery 라는 saga/effects 를 사용하여 action 들을 듣고 있습니다. (이벤트 리스너라고 생각하면 간단합니다.) 만약 LOGIN_REQUEST 액션이 들어오게 되면 loginAction 이라는 함수를 실행하고 _login 이라는 함수를 saga/effects에 call 를 사용하여 불러주죠. 그 다음 간단하게 timeout 를 사용하여 비동기 코드를 만들어주고, 이들이 실행 후 성공하면 saga/effects 에 put 를 이용하여 action 을 dispatch 시켜줍니다.
기본적인 saga 사용법인데, 더 디테일하게 알고 싶으시면 공식문서를 참고하시면 됩니다
공식문서가 생각보다 잘되어 있어서 좋습니다!
몇가지 saga/effects 에 대하여 알아보겠습니다.
먼저 함수를 부를 때 call, fork 를 사용하는데요. call 은 동기적 요청, fork 는 비동기적 요청입니다.
function asyncFunction() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("TIME OUT");
resolve();
}, 3000)
});
}
function* test() {
yield fork(asyncFunction);
yield console.log("FORK");
}
// result
// FORK
// TIME OUT
function* test() {
yield call(asyncFunction);
yield console.log("CALL");
}
// result
// TIME OUT
// CALL
어렵지 않죠?
그 다음에는 미들웨어란 무엇인가에 대하여 잠시 생각해보겠는데요.
미들웨어는, action 이 dispatch되어서 reducer 에서 이를 처리하기 전에 사전에 지정된 작업들을 처리하게 되는건데요.
좋은 글이 있어서 가져왔습니다.
앞서 보셨듯이 redux-saga 는 generator function 을 이용합니다.
generator function 에 대한 이해가 부족하면 좋은 글을 가져오겠습니다. 한번 읽어보세요.
대부분 구글 검색으로 쉽게 찾아볼 수 있는 블로그들입니다.
저 또한 많이 읽었고 이를 통해 많은 이해를 했습니다.
이정도로 redux-saga 에 대한 기본적인 것들은 끝내고 실제 프로젝트에 적용해보겠습니다.
사실 더 많은 정보들이 있지만 이는 검색을 통하여 찾아보시는게 훨씬 효율적이고 좋을것 같습니다.
그 전에 eslint 를 사용해서 airbnb coding style 로 프로젝트 스타일을 잡았는데, 이를 간단하게 적용해보겠습니다.
eslint.json
{
"parser": "babel-eslint",
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"env": {
"browser": true,
"node": true,
"es6": true
},
"extends": [
"airbnb"
],
"plugins": [
"import",
"react-hooks"
],
"rules": {
"no-underscore-dangle": "off",
"react/forbid-prop-types": 0,
"object-curly-newline": 0,
"react/jsx-filename-extension": "off",
"jsx-a11y/label-has-for": "off",
"jsx-a11y/label-has-associated-control": "off",
"no-console": "off",
"no-case-declarations": "off"
}
}
eslint 는 위와 같이 변경해 주시고 이를 적용하기 위해 몇가지 package 를 설치해야 합니다.
$ npm i -D babel-eslint eslint-config-airbnb eslint-plugin-jsx-a11y
이렇게 설치해 주시고 너무 restrict 한 rule 이 있다면 저처럼 reules 에 추가해주시면 됩니다.
이렇게 하면 코드 스타일이 조금 더 깔끔해 지신것을 확인 하실 수 있습니다.
일단 포스팅이 길어지니 프로젝트에 redux-saga 적용은 다음 포스팅으로 미뤄야겠습니다.
그럼 이만
'React JS' 카테고리의 다른 글
[React SNS] React SNS 만들기 - 5 (BackEnd server - Web server 만들기) (0) | 2019.08.13 |
---|---|
[React SNS] React SNS 만들기 - 4 - 2 (redux saga 적용) (0) | 2019.08.12 |
[React SNS] React SNS 만들기 - 3 (0) | 2019.08.06 |
[React SNS] React SNS 만들기 - 2 (0) | 2019.07.30 |
[React SNS] React SNS 만들기 - 1 (0) | 2019.07.29 |