이전에 만든 thunk 생성 함수의 리듀서를 만들어보자.
const initialState = {
posts: {
loading: false,
data: null,
error: null,
},
post: {
loading: false,
data: null,
error: null,
},
};
export default function posts(state, action) {
switch (action.type) {
case GET_POSTS:
return {
...state,
posts: {
loading: true,
data: null,
error: null,
},
};
case GET_POSTS_SUCCESS:
return {
...state,
posts: {
loading: false,
data: action.posts,
error: null,
},
};
case GET_POSTS_ERROR:
return {
...state,
posts: {
loading: false,
data: null,
error: action.error,
},
};
case GET_POST:
return {
...state,
post: {
loading: true,
data: null,
error: null,
},
};
case GET_POST_SUCCESS:
return {
...state,
post: {
loading: false,
data: action.post,
error: null,
},
};
case GET_POST_ERROR:
return {
...state,
post: {
loading: false,
data: null,
error: action.error,
},
};
default:
return state;
}
}
싶으면 util 함수를 작성한다.
lib/asyncUtils.js 라는 파일을 생성해서 reducerUtils 라는 함수를 작성한다.
-initial : posts 와 post 의 초기상태
initial: (data = null) => ({
data,
loading: false,
error: null
}),
※ 리팩토링
modules/posts.js
const initialState = {
posts: reducerUtils.initial(),
post: reducerUtils.initial()
},
2줄로 줄어들었다.
-loading : reducer에서 api 호출를 하는 경우 loading의 값이 변동된 데이터셋
loading: (prevState = null) => ({
data: prevState,
loading: true,
error: null
}),
prevState?
현재 posts.js 에서 api를 호출하는 action.type(GET_POSTS,GET_POST)의 경우, loading을 true로 변경하지만, 그와 동시에 data값까지 null로 바꿔버린다. 만약 data가 null로 바뀌는걸 원하지 않는 경우를 대비해서 이전의 상태값을 지정한 prevState로 data값을 정한 것이다.
success: (data) => ({
data,
loading: false,
error: null
}),
error: (error) => ({
data: null,
loading: false,
error
})
※ 리팩토링
export default function posts(state, action) {
switch (action.type) {
case GET_POSTS:
return {
...state,
posts: reducerUtils.loading(state.posts.data)
};
case GET_POSTS_SUCCESS:
return {
...state,
posts: reducerUtils.success(action.posts)
};
case GET_POSTS_ERROR:
return {
...state,
posts: reducerUtils.error(action.error)
};
case GET_POST:
return {
...state,
post: reducerUtils.loading(state.post.data)
};
case GET_POST_SUCCESS:
return {
...state,
post: reducerUtils.success(action.post)
};
case GET_POST_ERROR:
return {
...state,
post: reducerUtils.error(action.error)
};
default:
return state;
}
}
각각의 액션타입에서 변경되는 상태를 한줄로 간단하게 줄일수 있게 되었다.
다음에는 getPosts와 getPost. 이 두 thunk 생성함수의 내용이 유사한데, 이 둘을 리팩토링 해보자.