처음 만난 리덕스 (Redux) 문서


10.4 Async Function Middleware

앞에서는 Redux에서 Async Logic을 사용하기 위해서 middleware를 직접 만드는 방법에 대해서 배웠습니다.
하지만 앞에서 예시로 나왔던 middleware들은 범용적으로 비동기 로직을 적용하는 용도로 사용할 수 없고, 정해진 상황에서만 사용할 수 있는 middleware였습니다.

지금부터는 범용적으로 사용할 수 있는 Async Function Middleware라는 것을 만들어 보도록 하겠습니다.

const asyncFunctionMiddleware = store => next => action => {
    // action이 함수일 경우
    if (typeof action === 'function') {
        // dispatch와 getState를 파라미터로 하여 action 함수를 호출
        return action(store.dispatch, store.getState);
    }

    // 일반적인 action 객체일 경우, 원래대로 처리
    return next(action);
}

이 코드는 간단하게 만들어본 Async Function Middleware입니다.

이 middleware가 해주는 역할은 action이 함수일 경우 dispatch와 getState를 파라미터로 하여 action 함수를 호출해주고, 그 밖에 action이 일반적인 action객체일 경우 원래대로 처리하는 역할을 해줍니다.

그래서 이 middleware를 사용하면 action으로 객체가 아닌 함수를 전달할 수 있고, action이 함수일 경우 해당 함수 내에서 비동기 로직을 수행 할 수 있게 됩니다.

그럼 실제로 이 middleware가 적용된 Redux Store에서 사용하는 예시 코드를 한 번 볼까요?

const middlewareEnhancer = applyMiddleware(asyncFunctionMiddleware);
const store = createStore(rootReducer, middlewareEnhancer);

// 'dispatch'와 'getState'를 파라미터로 가지는 함수 작성
const fetchPosts = (dispatch, getState) => {
    // 비동기 HTTP 요청
    apiClient.get('posts').then(posts => {
        // 서버에서 받은 posts 데이터와 함께 action을 dispatch
        dispatch({ type: 'my-app/post/LOADED', payload: posts });
        // dispatch 이후 업데이트 된 store에서 데이터 확인
        const allPosts = getState().posts;
        console.log('로딩 이후 총 posts 개수: ', allPosts.length);
    });
}

// 작성한 fetchPosts 함수(action)를 dispatch
store.dispatch(fetchPosts);

// 로그 출력 예시:
// 로딩 이후 총 posts 개수: 10

이 코드는 앞에서 만든 Async Function Middleware가 적용된 Redux Store에서 실제로 비동기 작업을 처리하는 예시 코드입니다.

먼저 applyMiddleware() 함수를 사용해서 Async Function Middleware가 포함된 middlewareEnhancer를 만듭니다.
그리고 Redux Store를 생성하는 createStore() 함수의 두 번째 파라미터로 이 enhancer를 넣어줍니다.
이렇게 하면 Redux Store의 Action처리 과정에서 Async Function Middleware가 함께 동작하게 됩니다.

다음으로는 fetchPosts 라는 이름의 함수를 하나 만들었습니다.
이 함수는 dispatchgetState를 파라미터로 가지는데, Async Function Middleware에 넘기기 위한 형태라고 보면 됩니다.
함수 내에서는 비동기 작업이 이뤄지는데 여기서는 서버에 요청을 보내서 데이터를 받아오고, 데이터를 받아온 이후에 받은 데이터와 함께 action을 dispatch하게 됩니다.

그리고 마지막으로 작성한 fetchPosts() 함수를 dispatch합니다.
이렇게 dispatch된 함수 형태의 action은 Async Function Middleware에서 처리됩니다.

지금까지 Redux에서 비동기 로직을 사용하기 위해서 Async Function Middleware라는 것을 만들고 실제로 사용하는 과정에 대해서 알아보았습니다.
비동기 로직을 위해서 이렇게 직접 middleware를 만들어서 사용할 수도 있지만, 대부분의 경우에는 redux-thunkredux-saga같은 검증된 라이브러리들을 사용합니다.
여기에서는 Redux에서 비동기 로직을 처리하기 위해 middleware가 어떤 형태로 작성되고 사용되는지에 대해서만 잘 이해를 하고 넘어가기 바랍니다.


마지막 업데이트: 2023년 07월 14일 00시 00분

이 문서의 저작권은 이인제(소플)에 있습니다. 무단 전재와 무단 복제를 금합니다.