[React] Redux-middleware

JIOO·2022년 6월 8일
0

React

목록 보기
4/18
post-thumbnail

리덕스 미들웨어란 뭘까?

👩‍🎓 미들웨어는 액션을 디스패치 했을 때 부터 리듀서로 올때까지의 중간 허브같은 역할을 한다.

미들웨어 구조원리

미들웨어의 기본문법

const origin = store => next => action => {
  //미들웨어는 관습적으로 고차원함수로 파라미터를 3개씀.
  
  const result = next(action) or dispatch(action); 
  //미들웨어에서 할 게 없다고 판단 다음으로 액션을 넘기는 상황
  
  return result; 
  
};

export default origin;

------------------------------------------------------------------------------

// 쉽게 풀이하면 콜백 콜백 콜백 함수다
function middleware(store) {
  return function (next) {
    return function (action) {
      // 하고 싶은 작업...
    };
  };
};

미들웨어 적용방법

미들웨어를 사용하기 위해서는 스토어에 applyMiddleware라는 기능을 사용.

const store = createStore(rootReducer, applyMiddleware(미들웨어함수명));
//이렇게 넣어줌 

만약 미들웨어가 한개를 초과 할 경우 applyMiddleware(미들웨어함수명) 대신 

const enhancer = applayMiddleware (
  firstMiddleware,
  secondMiddleware
)

미들웨어는 원래 동기적

<button onclick={()=>{dispatch(increase())}}>up</button> 

클릭 하면 ↓

export const increase = () => ({ type : INCREASE }) 가 실행됨.

실행 되면서, store에 middleware가 있는 지 찾음 = myLogger 이라는 middleware를 발견 

const store = createStore(rootReducer, applyMiddleware(myLogger));

-----------------------------------------------------------------

myLogger.js (middleware)

const myLogger = store => next => action => {
// 여기서 해볼 수 있는게 
 
 console.log(action)
 → 해석(결과) :
 { type : INCREASE } // object 타입 
--------------------------------------------------------------

console.log(store.getState())
 → 해석(결과) :
store = getState = initialState  
--------------------------------------------------------------
// 마지막 처리 (next) ↓
 
 const result = next(action) //action을 다음 middleware로 넘김 
 
  return result 
  
}
// 근데 여기서 action이 object가 아니라 function 일 경우 비동기 함수 처리하는데 이걸 thunk라 함 

미들웨어의 비동기 처리 (실전사례)

기본 셋팅

const GET_USERS_START = 'GET_USERS_START';
const GET_USERS_SUCCESS = 'GET_USERS_SUCCESS';
const GET_USERS_FAIL = 'GET_USERS_FAIL';

export function getUsersStart() {
  return {
    type: GET_USERS_START,
  };
}
export function getUsersSuccess(data) {
  return {
    type: GET_USERS_SUCCESS,
    data,
  };
}
export function getUsersFail(error) {
  return {
    type: GET_USERS_FAIL,
    error,
  };
}

thunk 함수

function getUsersThunk() {
  return async (dispatch, getState) => {
    try {
      dispatch(getUsersStart());
      const res = await axios.get('https://api.github.com/users');
      dispatch(getUsersSuccess(res.data));
    } catch (e) {
      dispatch(getUsersFail());
    }
  };
}

const thunk = getUsersThunk();
thunk.withExtraArgument = getUsersThunk;

export default thunk;

store

import thunk from 'redux-thunk';


const store = createStore(
  reducer,
  composeWithDevTools(
    applyMiddleware(thunk),
  ),
);

App.js

export default function App() {
  useEffect(() => {
   getUsers();
 }, []);
}

↓

const getUsers = useCallback(() => { 
  // 함수가 재 실행 되지 않게 useCallback 사용 
 dispatch(getUsersThunk()); // 비동기 처리 thunk dispatch로 호출
}, [dispatch]);
  1. APP이 마운트 됐을 때 getUsers 함수를 실행
  2. getUsers에서 getUserThunk를 dispatch 하고 미들웨어에서 object or function 감지
  3. getUserThunk에서 dispatch와 getState를 받고 async try & catch로 비동기 처리
profile
프론트엔드가 좋은 웹쟁이

0개의 댓글