이번 시간에는 전에 만든 TodoApp에 redux-thunk 미들웨어를 사용하여
비동기적으로 리스트를 생성하는 작업을 진행하였다.
첫번째
npm i redux-thunk
위 처럼 thunk를 npm으로 설치해도 되고, 따로 작성해도 됀다.
따로 작성하더라도 몇 줄 되지 않으니, 따로 작성하도록 하겠다.
비동기 작업을 처리할 때 redux-saga와 많이 쓰이는 미들웨어
물론 redux-saga와는 기능은 차이가 있다. 그 부분은 추후 정리해보자.
일단 여기에서는 Thunk만 사용해서 비동기 작업을 할 것이다.
실제로 api를 사용하는 것은 아니고, setTimeout
으로 비동기처럼
보이도록 작업을 진행했다.
// 고차함수의 형태를 가지고 있다.(외우자)
// 아래 같은 고차함수로 원하는 기능을 만들 수 있다. ex) logging하는 기능
const thunkMiddleware = (store) => (next) => (action) => {
// action이 함수일 경우 비동기
if (typeof action === 'function') {
// 아래처럼 실행한다.
return action(store.dispatch, store.getState);
}
return next(action);
};
const middleware = [thunkMiddleware];
const store = createStore(reducer, applyMiddleware(...middleware));
이 부분은 이해를 하는데 있어서 어려운 부분들이 있다.
일단 thunkMiddleware
가 가지고 있는 세가지 인자는 모두
applyMiddleware
에서 받는다고 한다.
store
- dispatch , getState의 정보를 담고 있다.
next
- 다음 미들웨어에 action을 전달한다. 하지만,
return으로 전달하지 않을경우, 리듀서에서 처리하지 않는다.
action
- 전달받은 action에 대한 정보를 담고 있다.
export const addTodoList = (data) => {
// return이 함수면, thunk에서 처리를 한다.
return (dispatch, getState) => {
console.log(getState()); // 현재 state
setTimeout(() => {
dispatch(addTodo(data)); // 1초 후 실행
}, 1000);
};
};
export const addTodo = (data) => {
return {
type: ADD_TODO_LIST,
data,
};
};
redux-thunk를 사용하기 위해서 addTodoList
의 return값을
함수로 진행한다. 이렇게 진행하면 action과 reducer의 사이에 있는
thunkMiddleware
에서 처리한다.
1초 뒤 addTodo
가 실행하게 되고, reducer로 넘어가서
최종 작업을 처리한다.
처리 흐름을 알고 싶어서 console로 모든 작업 코드에 넣어보았다.
처음은 당연히 컴포넌트에서 실행할 때 즉 addTodoList
함수다.
const onAddList = useCallback(() => {
if (value === '') {
return alert('내용을 입력해주세요.');
}
dispatch(
addTodoList({
id: shortId.generate(),
title: value,
done: false,
}),
);
setValue('');
}, [value]);
addTodoList
함수 실행 후, thunkMiddleware
에서 action이
함수인걸 확인한다. 그리고 addTodoList
의 return 작업이 실행된다.
그 후 addTodo
action이 실행되고, reducer로 넘어가서 처리된다.
그렇게 TodoApp thunk로 작업하기 마무리!
추후 실제 api로 작동을 해보고 싶으니... saga까지 익혀보고
진행해보자!