React.js Redux Advanced
11 Feb 2021 | ReactReact.js Redux Advanced
-
Redux Middleware
- 미들웨어를 사용하면 action이 dispatch된 다음, reducer에서 해당 action을 받아와서 업데이트하기 전에 추가적인 작업을 할 수 있다
- 추가적인 작업이란 특정 조건에 따라 액션이 무시되게 만들거나, 액션을 콘솔 혹은 서버사이드에 로깅하거나, 디스패치된 액션을 수정해서 리듀서에게 전달하거나, 특정 액션이 발생했을 때 이에 기반하여 다른 액션 혹은 자바스크립트 함수를 실행시키는 등의 것들이다
- 미들웨어는 주로 asynchronous works(비동기 작업) 처리에 사용된다
/* 미들웨어 직접 만들기 */ import { createStore, applyMiddleware } from 'redux'; import reducer from 'path/reducer'; const logger = store => { // store를 파라미터로 받음 return next => { // 액션을 다음 미들웨어에게 전달, 다음 미들웨어가 없으면 리듀서에게 액션을 전달 return action => { // 현재 처리하고 있는 액션 console.log(action); const result = next(action); console.log(store.getState()); return result; } } }; const store = createStore(reducer, applyMiddleware(logger)); ReactDom.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
-
Redux Devtools extension
- 크롬 확장앱인 redux devtools로 현재 store의 state 조회, dispatch된 action 등을 확인할 수 있다
/* index.js에 다음을 추가 (미들웨어를 사용할 경우 적용법) */ const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const store = createStore(reducer, composeEnhancers(applyMiddleware(logger)));
-
Action Creator
- 지금까지는 action을 하드코딩으로 때려넣었다
/* 지금까지의 코드 */ const mapDispatchToProps = dispatch => { return { onAddCounter: () => dispatch({type: actionTypes.ADD, val: 10}); } };
- action creator 메소드를 생성하여 dynamic하게 action을 생성할 수 있다
- 이렇게 코드를 짜면 비동기 작업을 처리할 때 유용하다
/* actions.js */ export const ADD = 'ADD'; export const add = (value) => {// action creator return { type: ADD, val: value, }; };
import * as actionCreators from 'actions'; const mapDispatchToProps = dispatch => { return { onAddCounter: () => dispatch(actionCreators.add(10)); } };
-
redux-thunk
- redux-thunk는 비동기 작업을 처리할 때 가장 많이 사용하는 미들웨어이다
- redux-thunk를 이용하면 액션 객체가 아닌 함수를 디스패치 할 수 있다
- 위 코드처럼 action을 바로 return 하지 않고 함수로 감쌌기 때문에 작업을 뒤로 미룰 수 있다
- npm install –save redux-thunk
/* index.js */ import thunk from 'redux-thunk'; const store = createStore(reducer, composeEnhancers(applyMiddleware(logger, thunk))); //미들웨어 삽입
/* actions.js */ export const add = (value) => { return { type: ADD, val: value, }; }; export addAsync = (value) => {// thunk로 비동기 처리 return dispatch => { setTimeout(()=> { dispatch(add(value)) }, 2000); } };
- 위의 코드에서 thunk는 두 번째 파라미터로 getState를 받으면 store의 현재 state에도 접근할 수 있다
- 현재 state에 따라서 dispatch 여부를 결정하는 등 logic을 세울 수 있다
- state를 직접 바꾸는 것도 가능하나, getState의 남용보다는 reducer에서 처리하는 것이 좋다
export addAsync = (value) => {// thunk로 비동기 처리 return (dispatch,getState) => { const oldState = getState().state; // 현재 state에 접근 console.log(oldState); setTimeout(()=> { dispatch(add(value)) }, 2000); } };