Redux의 추가 리듀서들
상품 애플리케이션을 열고,
그 안의 productsSlice.js 파일을 열어 보겠습니다. 아마도 여러분은
thunk fetchProducts를
별도의 함수로 생성한 것을
눈치챘을 것입니다? 우리가 이렇게 한 이유는
createSlice가 thunk 정의를
지원하지 않기 때문입니다. 그렇다면 이 경우에
products 슬라이스의 리듀서가
슬라이스 외부에서 정의된 액션들에
반응하도록 어떻게 할 수 있을까요?
우리는 바로 thunk fetchProducts가
보내는 액션들을 처리해야 합니다.
이러한 경우를 위해 createSlice에는
추가 리듀서들을 추가할 수 있는
extraReducers 속성이 있으며,
이 리듀서들은 해당 슬라이스에서
정의되지 않은 액션들을 처리하게 됩니다.
이제 createSlice 함수 본문 내에서
모든 리듀서들이 있는 reducers 속성 뒤에
extraReducers 메서드를 하나 더 추가해 보겠습니다:
extraReducers() {},
이 메서드에는 추가 리듀서들을
추가할 수 있는 메서드들을 가진
builder 객체를 전달해야 합니다:
extraReducers(builder) {},
우리는 builder의 메서드 중 하나인
addCase를 사용할 것입니다. 이 메서드는
첫 번째 매개변수로 action creator를,
두 번째 매개변수로 reducer를 받습니다.
fetchProducts가 요청 시 보낼 액션 중 하나는
fetchProducts.pending로, 요청이 전송되었음을 알립니다.
이 경우 상태를 'in progress'로
변경하겠습니다 (이전 상태는 'idle'였습니다):
extraReducers(builder) {
builder.addCase(fetchProducts.pending, (state) => {
state.status = 'in progress'
})
},
이제 요청이 성공적으로 완료되었을 때 전송되는 액션을 처리해 보겠습니다.
여기서는 상태의 상태를 'success'로 변경하는 것뿐만 아니라,
액션의 payload에서 products 슬라이스로 상품들을 가져올 것입니다.
모든 상품들을 수집하려면 concat 메서드가 필요할 것입니다:
extraReducers(builder) {
builder
.addCase(fetchProducts.pending, (state) => {
state.status = 'in progress'
})
.addCase(fetchProducts.fulfilled, (state, action) => {
state.status = 'success'
state.products = state.products.concat(action.payload)
})
},
요청이 실패한 경우에는
상태를 'fail'로 변경하고
상태에 오류 메시지를 기록하겠습니다:
.addCase(fetchProducts.rejected, (state, action) => {
state.status = 'fail'
state.error = action.error.message
})
만약 지금 애플리케이션을 실행하고
메뉴에서 'Products'를 클릭하면,
몇 초 후 (서버에 설정한 지연 시간을 기억하시나요?) 상품 목록을 볼 수 있을 것입니다.
마찬가지로 Redux DevTools에서도 변경 사항을 확인할 수 있습니다.
이제 여러분의 상품들이 상태에 나타날 것입니다 ('State' 탭을 확인하세요),
products/fetchProducts/fulfilled 액션을 클릭한 경우에요.
거기에 새로운 상태 'success'도 나타날 것입니다.
이제 products/fetchProducts/pending 액션을 클릭하고,
'State' 탭이 어떻게 달라졌는지 확인해 보세요.
발생할 수 있는 유일한 불편한 점은
(저번 강의에서 이에 대해 말씀드렸습니다) 데이터 요청의 중복입니다.
그 결과, 우리 목록에 8개가 아닌
무려 16개의 상품이 생기고 개발자 콘솔에
심각한 경고가 나타날 수 있습니다.
다음 강의에서 이 문제를 해결해 보겠습니다.
학생 관리 애플리케이션을 열어 보세요.
그 안의 studentsSlice.js 파일을 열어 보세요.
createSlice 함수 본문 내에서
reducers 속성 뒤에 extraReducers 속성을 추가하세요.
extraReducers 메서드에 builder를 전달하세요.
builder.addCase 메서드를 사용하여
강의에서 보여준 것처럼 데이터 요청 시
fetchStudents가 전송하는 pending,
fulfilled 및 rejected 액션들에 대한 처리를 추가하세요.