As i wish

[React SNS] React SNS 만들기 - 4 - 1 (redux saga 란, airbnbStyle applied) 본문

React JS

[React SNS] React SNS 만들기 - 4 - 1 (redux saga 란, airbnbStyle applied)

어면태 2019. 8. 12. 12:26

안녕하세요. 엄티입니다.

계속해서 React 를 사용해서 SNS 를 만들어 보겠습니다.

 

프로젝트 소개와 프로젝트 구성 요소는 제 전 포스팅을 참고해주세요.

React SNS 만들기 - 1

 

[React SNS] React SNS 만들기 - 1

안녕하세요. 엄티입니다. 오늘은 React 를 사용하여 간단한 SNS 를 만들어 볼껀데요. 제 포스팅은 '제로초' 님의 강의를 바탕으로 복습용으로 작성됩니다. 자세한 설명을 원하면 밑에 강의를 참조해 주세요. '제로..

eomtttttt-develop.tistory.com

참고로 제 포스팅은 '제로초' 님의 SNS 만들기 강좌 복습 포스팅입니다.

'제로초' 님의 React NodeBird SNS

 

React로 NodeBird SNS 만들기 - 인프런

리액트&넥스트&리덕스&리덕스사가&익스프레스 스택으로 트위터와 유사한 SNS 서비스를 만들어봅니다. 끝으로 검색엔진 최적화 후 AWS에 배포합니다. 중급 웹 개발 프레임워크 및 라이브러리 서비스 개발 Front End Back End Javascript React 온라인 강의

www.inflearn.com

 

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에 동작에 대하여 프로젝트를 만들었는데, 한번 확인해 보겠습니다.

간단한 redux-saga login project

 

eomttt/react-study

React study by react web game. Contribute to eomttt/react-study development by creating an account on GitHub.

github.com

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 사용법인데, 더 디테일하게 알고 싶으시면 공식문서를 참고하시면 됩니다

redux-saga gitbook

 

읽어주세요 · GitBook

No results matching ""

mskims.github.io

공식문서가 생각보다 잘되어 있어서 좋습니다!

 

몇가지 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 에서 이를 처리하기 전에 사전에 지정된 작업들을 처리하게 되는건데요.

좋은 글이 있어서 가져왔습니다.

 

미들웨어란?

 

리덕스 미들웨어, 그리고 비동기 작업 (외부데이터 연동) | VELOPERT.LOG

이 문서는 패스트캠퍼스 오프라인 강의를 위해서 준비된 문서이기에, 일부 내용들은 설명이 생략되어있을 수도 있습니다. 이번 강의에서 다룰 주제는 리덕스 미들웨어를 사용하여 외부 데이터를 연동하는 방법을 다뤄보겠습니다. 외부 데이터를 연동하기 위해서 리덕스, 그리고 리덕스 미들웨어들이 꼭 필요한것은 아닙니다. 리액트 컴포넌트와 내부 state 만을 사용하여 모든 것 들을 할 수 있어요. 하지만, 좋은 도구들과 함께하면 좋은 개발자경험 (Developer Ex

velopert.com

 

앞서 보셨듯이 redux-saga 는 generator function 을 이용합니다.

generator function 에 대한 이해가 부족하면 좋은 글을 가져오겠습니다. 한번 읽어보세요.

 

generator function  이란?

 

(ECMAScript) ES2015(ES6) 반복기(iterator), 생성기(generator) - 비동기코드를 동기처럼

 안녕하세요. 이번 시간에는 반복기와 생성기에 대해서 알아보겠습니다. 이름만 들었는데도 생소해 보이죠? 반복되는 객체를 직접 만드는 기능입니다. 어떻게 사용되는지 봅시다. 반복기 let factorial = { [Symbol.iterator]() { l

www.zerocho.com

redux-saga VS redux-thunk

 

Redux-Thunk vs Redux-Saga를 비교해 봅시다!

Redux-Thunk vs Redux-Saga thunk saga 이글은 Decembersoft 페이지글은 번역한 글입니다. 당신은 Redux tutorials를 이미 끝냄으로써, 당신만의 Redux code를 테스트할 준비가 되었다고 느낄 것입니다. 피와 땀, 눈물을 흘린 후에 당신은 reducer와 몇 가지 action들을 구현했습니다. 당신은...

velog.io

redux-saga sideEffect 

 

Redux-Saga: 사이드 이펙트 관리 : TOAST Meetup

Redux-Saga: 사이드 이펙트 관리

meetup.toast.com

Why redux-saga?

 

왜 리덕스 사가(Redux-saga) 인가?

redux, redux-thunk, redux-promise-middleware, redux-actions, redux-saga 머리가 뽀개질 지경이다. 결국엔 redux-saga를 써야만 했고 왜 saga로 수렴하게 되는지에 대한 삽질기다.도대체 몇 개의 미들웨어 라이브러리를 파야하는지 화남을 포스팅했기에 오 프론트엔드를 꾸미는데는 리액트가 최고야 라고

gracefullight.dev

redux-saga async control

 

redux-saga를 활용한 Redux 비동기 액션 처리

Redux 를 사용하면 React 앱에서 데이터를 처리하는 비즈니스 로직을 컴포넌트로부터 분리할 수 있다. 그리고 비즈니스 로직은 보통 액션 객체를 반환하는 액션 생성자 함수 내부에서 작성하는 방식이 권장된다. 그런데 액션 생성자 함수에서 API 호출 같은 비동기…

blog.rhostem.com

대부분 구글 검색으로 쉽게 찾아볼 수 있는 블로그들입니다.

저 또한 많이 읽었고 이를 통해 많은 이해를 했습니다. 

 

이정도로 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 에 추가해주시면 됩니다.

이렇게 하면 코드 스타일이 조금 더 깔끔해 지신것을 확인 하실 수 있습니다.

 

airbnb style applied

 

[4-1 ~ 9] Fix eslint-airbnb style · eomttt/react-sns@40d43ec

 

github.com

 

일단 포스팅이 길어지니 프로젝트에 redux-saga 적용은 다음 포스팅으로 미뤄야겠습니다.

그럼 이만

Comments