-
[REACT] Redux, Redux-Thunk, Redux-SagaReact, Next 2022. 8. 14. 01:33
Redux 세팅 방법
store > configureStore.js
import { createWrapper } from "next-redux-wrapper" import { applyMiddleware, compose, createStore } from "redux" import { composeWithDevTools } from "redux-devtools-extension" import reducer from "../reducers" const configureStore = () => { const middlewares = [] const enhancer = process.env.NODE_ENV === "production" ? compose(applyMiddleware(...middlewares)) : composeWithDevTools(applyMiddleware(...middlewares)) // 개발자모드에서 DevTools 사용 세팅한다. const store = createStore(reducer, enhancer) return store } const wrapper = createWrapper(configureStore, { debug: process.env.NODE_ENV === "development", }) export default wrapper
middlewares
리덕스에 없는 기능을 추가해서 성능을 확장시켜주는 역할을 한다. 리덕스 세팅에 middlewares 안에 Thunk나 Saga를 추가적용 할 수 있다.
Redux-Thunk / Redux-Saga
둘 다 비동기 action을 dispatch할 수 있도록 도와주는 역할을 한다.
아래 코드를 보면 setTimeout 함수 안에 dispatch를 한 것을 볼 수 있다.
const INCREMENT_COUNTER = 'INCREMENT_COUNTER' function increment() { return { type: INCREMENT_COUNTER } } function incrementAsync() { return dispatch => { setTimeout(() => { // Yay! Can invoke sync or async actions with `dispatch` dispatch(increment()) }, 1000) } }
비동기 action을 dispatch 하게되면 장점은 무엇일까?
하나의 비동기 액션 안에 여러개의 동기 액션을 할 수 있다
예를 들면 axios 요청을 보낼 때 LoadPostRequest 액션을 dispatch하고, 성공했을 땐 LoadPostSuccess를, 실패했을 땐 LoadPostFailer dispatch하는 식으로 여러번의 액션을 보낼 수가 있다.
Redux-Thunk 사용방법
우선 패키지를 설치한다.
npm i redux-thunk
import 해준 모듈을 middlewares 배열에 넣어주면 된다.
... import thunkMiddleware from 'redux-thunk'; ... const configureStore = () => { const middlewares = [thunkMiddleware] ... } ... export default wrapper
Redux-Thunk가 제공하는 기능 외에 내맘대로 로직을 커스텀 하고싶다면?
https://github.com/reduxjs/redux-thunk/blob/master/src/index.ts
Redux-Thunk 깃허브에서 코드를 타고 들어간뒤
위 코드가 Redux-Thunk의 핵심이다. 아래 코드를 통해 자세히 살펴보자.
({ dispatch, getState }) => next => action => { // action이 원래는 객체인데 redux-thunk에서는 action을 function으로 둘 수 있다. action이 function이면 지연함수이기 떄문에 그 액션을 나중에 실행시켜줄 수 있다. // 이 action이 실제로 함수라면 호출하고 결과를 반환한다. if (typeof action === 'function') { return action(dispatch, getState) } // 그렇지 않으면 평소와 같이 미들웨어 체인 아래로 작업을 전달한다. return next(action) }
하지만 위 코드를 수정하면서 내 마음대로 dispatch가 일어나기 전에 로직을 추가/수정 할 수 있다.
const loggerMiddleware = ({ dispatch, getState }) => next => action => { console.log(action) return next(action) } const configureStore = () => { const middlewares = [thunkMiddleware, loggerMiddleware] ... }
고차함수로 이루어져 있는 저 loggerMiddleware 라는 함수에서 next, action과 같은 매개변수를 가져오기 때문에, 이것을 활용해 dispatch가 이루어지기 전에 먼저 실행할 로직을 넣어줄 수 있다. 위 코드의 경우 dispatch가 이루어지기 전에 action을 콘솔로 찍어준다.
실제로 로그인, 로그아웃 action을 요청한 뒤 개발자도구를 열어보니 콘솔에 찍힌 것을 확인할 수 있다.
Redux-Saga
Redux-Thunk보다 더 많은 기능을 제공해준다. 예를들어 클릭을 짧은시간에 여러번 클릭했을 땐 어떻게 처리할 것인지? 이런 부분을 Thunk에서는 직접 구현해야 하지만 Saga에서는 takeLatest, trottle 등 한번에 해결해주는 여러가지 메소드가 존재한다.
Redux-Saga 사용방법
npm i redux-saga
리덕스 사가의 경우에는 여기저기 세팅할 부분들이 좀 있다.
1. 우선 import를 해준 뒤 sagaMiddleware라는 변수에 createSagaMiddleware를 호출하여 넣어준다.
2. middlewares 배열에 sagaMiddleware를 넣어준다.
3. store 변수에는 sagaTask라는 메서드가 있는데, 아래 코드에 '핵심' 이라고 쓰여있는 부분의 세팅을 하자.
import createSagaMiddleware from "redux-saga" import rootSaga from "../sagas" const configureStore = () => { const sagaMiddleware = createSagaMiddleware() const middlewares = [sagaMiddleware, loggerMiddleware] ... const store = createStore(reducer, enhancer) store.sagaTask = sagaMiddleware.run(rootSaga) 🔥핵심 return store } ...
Generate 함수
설명 넣기
Saga의 다양한 Effect- all : fork나 call로 실행하는 것들을 동시에 전부 실행할 수 있게 해준다.
- take : 지정한 action이 실행될 때까지 기다리겠다. 지정된 action이 실행되면 지정해둔 generate 함수를 호출한다.
- fork : 함수를 실행하는 것. 비동기 함수 호출. API가 반환되는 것을 받아오기 전에 다음 코드가 실행되어버린다.
- call : 함수를 실행하는 것. 동기함수 호출. API가 반환해준 것을 받아올 수 있다. async await 같은 느낌이라고 보면 된다.
- put : dispatch라고 보면 된다. 액션을 실행시키는 놈인데, Rest API를 통해 반환받은 값을 함께 전달하며 실행시킬 수 있다.
- takeEvery : take로 만든 함수는 한번 실행되면 사라져버리는데, 이건 그 함수를 무한하게 사용할 수 있다. 마치 while(true)로 감싸는 느낌이다.
- takeLatest🔥 : 클릭을 실수로 2번 눌렀을 때 앞에 누른건 무시되고 마지막 클릭만 실행시킨다.
주로 이거 쓴다. - takeLeading : takeLatest과 비슷하지만 이건 맨 첫번째 클릭만 실행되고 나머지를 무시한다.
- throttle🔥 : 시간을 설정해두고 그 시간동안에는 클릭을 여러개 해도 하나만 보내지도록 한다.
이것도 중요 - debounce : 검색창에 타이핑할 때 자동완성 데이터를 불러오는 부분에서 주로 사용한다. 어떤 단어가 완성될 때 요청보내는 식으로 정할 수 있다. throttle과 기능적으로 비슷한데 미묘한 차이가 있다고 하니 사용할 때 찾아보도록 하자!
- delay : 정해준 시간이 지난 뒤에 다음 코드를 실행시키게 한다.
이외에도 takeMaybe 등이 있다.
'React, Next' 카테고리의 다른 글
체크박스, 라디오버튼 만들기 (0) 2022.08.22 텍스트에디터? (0) 2022.08.18 버츄얼 돔? (0) 2022.08.15 불변성에 대하여 (0) 2022.08.14 react.lazy와 suspense (0) 2022.08.14