Redux 미들웨어(Middleware)는 액션이 디스패치되는 시점과 리듀서가 실행되는 시점 사이에 동작하는 확장 기능입니다. 미들웨어는 Redux의 동작을 변경하거나 확장하여 비동기 작업, 로깅, 예외 처리 등을 처리할 수 있도록 도와줍니다.
Redux 미들웨어는 액션을 받아서 변경하거나, 특정 조건에 따라 액션을 무시하거나 변형하거나, 액션이 리듀서에 도달하기 전후에 원하는 작업을 수행할 수 있습니다. 또한, 비동기 작업을 처리하기 위해 액션을 지연시키거나, 다른 액션을 디스패치하여 상태 업데이트를 관리하는 등의 기능을 제공할 수 있습니다.
-chatGPT
Middleware는 dispatch()를 통해서 reducer에게 action을 전달하기 전에 로깅, 비동기 API와 통신, 라우팅 등을 위해 사용된다.
const loggerMiddleware = (store:any) => (next:any) => (action:any) => {
console.log("store", store);
console.log("action", action);
next(action);
}
loggerMiddleware는 currying 함수로 구현되어있다. 첫 번째 인자는 store, 두 번째 인자는 다음 미들웨어 함수를 호출하는 함수, 세 번째 인자는 action이다.
const middleware = applyMiddleware(loggerMiddleware);
const store = createStore(rootReducer, middleware);
applyMiddleware()을 통해서 middleware를 생성한 후에 store객체를 생성할 때 middleware를 같이 등록해주면 된다.
redux Thunk는 Redux와 함께 사용되는 미들웨어(middleware)입니다. 미들웨어는 액션과 리듀서 사이에서 동작하며, 액션의 디스패치(dispatch)를 가로채서 추가적인 동작을 수행하거나 비동기 작업을 처리할 수 있습니다.
Redux Thunk는 Redux 액션 생성자(action creator)가 일반적인 객체 대신 함수를 반환할 수 있게 해줍니다. 이 함수는 Redux Thunk 미들웨어에 의해 인식되고 처리됩니다. 이 함수는 디스패치(dispatch) 함수를 인자로 받으며, 비동기 작업을 수행하고 필요한 시점에 액션을 디스패치할 수 있습니다.
-chatGPT
Thunk라는 단어는 일부 지연된 작업을 수행하는 코드 조각을 의미하는 용어이다. 일부 논리를 실행하는 대신 나중에 작업을 수행하는데 사용할 수 있는 함수 본문이나 코드를 작성할 수 있다.
여러 경우가 있지만 서버에 요청을 보내서 Data를 가져올 떄 주로 비동기 요청을 보낸다.
enum ActionType {
FETCH_POSTS = "FETCH_POSTS",
DELETE_POSTS = "DELETE_POSTS"
}
interface Post {
userId: number;
id: number;
title: string;
}
interface Action {
type: ActionType;
payload: Post[];
}
const posts = (state = [], action: Action) => {
switch (action.type) {
case 'FETCH_POSTS':
return [...state, ...action.payload];
case 'DELETE_POSTS':
return state.filter(item => item !== action.payload[0])
default:
return state;
}
}
export default posts;
먼저 action이 function인 경우에는 에러가 발생하므로 이를 다룰 수 있는 라이브러리가 필요하다.
npm install redux-thunk --save
이후에 store 객체를 생성하기 전에 생성했던 middleware객체에 라이브러리의 thunk 객체를 같이 인자로 넣어 생성한다.
const middleware = applyMiddleware(thunk,loggerMiddleware);
const store = createStore(rootReducer, middleware);
useEffect(() => {
dispatch(fetchPosts());
}, [dispatch])
export const fetchPosts = (): any => async (dispatch: any, getState: any) => {
const response = await axios.get("https://jsonplaceholder.typicode.com/posts");
dispatch({ type: 'FETCH_POSTS', payload: response.data });
원리는 위와 같다. Action이 함수가 아닐 경우에는 reducer에게 전달하고 함수일 경우에는 dispatch와 getState를 함수의 인자로 넘긴다.
이를 이용해 axios 요청을 보내고 받아온 값을 dispatch를 이용해서 store에게 action을 전달하는 방식이 thunk이다.