Redux 미들웨어 없이 비동기 처리하기
배경
소규모 어드민 프로젝트를 시작하면서 Redux 미들웨어를 쓰지 않기로 했다. redux-thunk는 간단하지만 액션 크리에이터가 비대해지고, redux-saga는 러닝커브가 있었다. 팀원 모두 Redux를 처음 쓰는 상황이라 더 단순한 방법을 찾았다.
구현 방식
컴포넌트에서 API를 호출하고, 성공/실패 시 동기 액션만 디스패치하는 방식이다.
class UserList extends Component {
componentDidMount() {
this.fetchUsers();
}
fetchUsers = async () => {
this.props.dispatch({ type: 'FETCH_USERS_REQUEST' });
try {
const response = await fetch('/api/users');
const users = await response.json();
this.props.dispatch({ type: 'FETCH_USERS_SUCCESS', payload: users });
} catch (error) {
this.props.dispatch({ type: 'FETCH_USERS_FAILURE', payload: error });
}
}
render() {
// ...
}
}
Reducer는 동기 액션만 처리하면 되어 간단했다.
function userReducer(state = { loading: false, data: [], error: null }, action) {
switch (action.type) {
case 'FETCH_USERS_REQUEST':
return { ...state, loading: true, error: null };
case 'FETCH_USERS_SUCCESS':
return { loading: false, data: action.payload, error: null };
case 'FETCH_USERS_FAILURE':
return { ...state, loading: false, error: action.payload };
default:
return state;
}
}
한계
재사용성이 떨어진다. 같은 API를 여러 곳에서 호출하면 로직이 중복된다. 유틸 함수로 분리해도 컴포넌트가 디스패치 로직을 알아야 한다.
규모가 커지면 결국 미들웨어가 필요할 것 같다. 하지만 지금은 이 방식이 팀에게 더 직관적이었다.