학습했던 내용을 정리하기 위해 작성된 글이며 다소 부정확한 내용이 포함될 수 있음을 양해바랍니다.
이미 게시된 글이라도 복습하는 과정에서 내용이 보완 또는 수정될 수 있습니다.
리덕스는 기본적으로 동기적인 상태 업데이트를 수행한다. 만약 비동기적으로 상태를 업데이트해야 한다면, redux-thunk라는 미들웨어를 사용할 수 있다. thunk를 사용하면 액션 크리에이터가 액션을 리턴하는 대신 함수를 리턴할 수 있다. thunk가 action creator에 직접 개입하는 것은 아니다. 리듀서가 순수한 액션 객체를 인수로 받는 것과 달리, 미들웨어는 특정한 액션(여기서는 함수를 리턴하는 액션)을 인식하여 커스텀된 로직을 실행한다. 즉 미들웨어를 통해 커스텀 된 dispatch를 실행할 수 있다. 그래서 특정 액션이 실행되는 것을 지연시키거나 특정한 조건이 충족될 때 액션이 실행될 수 있도록 한다.
//store.js
import { applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducer';
const store = createStore(reducer, applyMiddleware(thunk));
export default store;
미들웨어를 사용하기 위해서는 applyMiddleware를 import, 그리고 위 코드처럼 thunk를 적용시킨다.
//App.jsx
//Thunk를 사용하지 않는 경우
import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { fetchRegions } from './api';
import { updateRegions } from '../actions';
async function loadRegions() {
const url = 'https://blabla.com';
const data = await fetchRegions();
dispatch(updateRegions(data));
}
export default function App() {
const dispatch = useDispatch();
useEffect(() => {
loadRegions();
}, []);
return (
<div>
...
</div>
);
}
useEffect, fetch를 통해 초기 데이터를 불러오기 위해서는 컴포넌트에서 비동기적 코드를 작성해야 한다. fetch를 분리시켜 주었음에도 앱의 규모에 따라 로직이 복잡해질 가능성이 다분해 보인다.
만약 thunk를 사용한다면 코드가 더 간결해질 수 있다.
//App.jsx
//Thunk를 사용한다면?
import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { loadRegions } from '../actions';
export default function App() {
const dispatch = useDispatch();
useEffect(() => {
dispatch(loadRegions());
}, []);
return (
<div>
...
</div>
);
}
컴포넌트가 더 이상 비동기적 함수를 포함하지 않아도 된다. 대신 thunk로 작성된 action creator를 dispath한다.
//actions.js
import { fetchRegions } from './api';
export function updateRegions(regions) {
return {
type: 'updateRegions',
payload: {
regions,
},
};
}
export function loadRegions() {
return async (dispatch) => {
const regions = await fetchRegions();
dispatch(updateRegions(regions));
};
}
여기서 loadRegions는 일반적인 action creator가 아니다. 액션 객체를 리턴하지 않기 때문이다. loadRegions는 thunk에 의해 dispath, getState(optional) 메서드를 인수로 받는 함수를 리턴할 수 있다. loadRegions는 fetch 함수를 통해 데이터를 전달받아 다른 액션을 디스패치한다. 비동기적 프로세스로 다른 액션을 디스패치할 수 있는 함수인 셈이다.
'React' 카테고리의 다른 글
React defaultProps (0) | 2022.01.24 |
---|---|
의존성 주입이란 무엇인가? (0) | 2021.09.19 |
React-Redux 저장소(Store) 생성하기 (0) | 2021.09.10 |
Flux와 MVC의 차이에 대해 공부하기 (0) | 2021.08.30 |