기존에 redux를 사용해 react를 공부할 때 사용했던 코드로 middleware thunk에 history를 포함시켜 middleware 내부에서 history를 사용해 다른 페이지로의 전환이 가능하게 만들어 사용하는 방식으로 공부를 했다.
// configureStore.jsx
import thunk from "redux-thunk";
const middlewares = [thunk.withExtraArgument({ history: history })];
const enhancer = composeEnhancers(applyMiddleware(...middlewares));
// user.jsx
const signupFB = (nickname, pwd, pwd2) => {
return function (dispatch, getState, { history }) {
console.log(nickname, pwd, pwd2)
axios({
method:'post',
url : `${urll}api/users/register`,
data:{
nickname : nickname,
password : pwd,
confirmPassword : pwd2,
}
}).then(function (response){
history.push("/");
}).catch((err) => {
console.log(err)
})
}
};
하지만 프로젝트를 진행하며 개발단계에서 의도치 않은 에러를 없애고 성능의 향상을 위해 리덕스 툴킷, 타입스크립트, react-router-dom(v6)를 사용하게 되면서 middlewarer는 createAsyncThunk를 사용하게 되었고 history가 아닌 useNavigate를 사용하게 됐습니다.
그래서 createAsyncThunk에 navigate를 전달해 middleware 내부에서 비동기 통신이 끝난 후 페이지를 로딩해주려했으나 navigate를 전달할 방법이 없었습니다. 그렇게 수차례 시도하면서 알게 된 것은 '굳이 middleware에서 처리할 필요가 없다.' 입니다.
// pages/partyInfo.tsx
const test = async () => {
try {
await dispatch(getPartyInfo(1));
navigate("/");
} catch (err) {
console.log(err);
}
};
// partyInfoSlice.tsx
export const getPartyInfo = createAsyncThunk(
"partyInfo/getPartyInfo",
async (groupId: number, { rejectWithValue }: any) => {
try {
const response = await axios({
method: "get",
url: `${url}/get/test`,
data: {
groupId,
},
});
return response.data.group;
} catch (err: any) {
return rejectWithValue(err.response.data);
}
}
);
// extraReducer
extraReducers: (builder) => {
builder.addCase(getPartyInfo.fulfilled, (state, { payload }) => {
state.group = payload;
});
builder.addCase(getPartyInfo.rejected, (state, action) => {
state.group.groupId = -1;
});
},
위와 같이 page에서 async, await를 이용해 redux와 서버와 통신을 하고 그에 따른 에러를 처리해줄 수 있습니다.
page에서 dispatch(getPartyInfo(1))을 하면 1은 getPartyInfo에 있는 groupId로 값이 전달되어 사용할 수 있게 됩니다. 또한, rejectWithValue를 이용하여 에러를 가져와 반환해줄 수 있게 되고 이를 return 받아 에러 처리를 할 수 있게 되며 extraReducers에서는 통신이 거부되었을 때의 상태값을 설정할 수 있게 됩니다.
이처럼 이벤트가 발생하는 곳(page), 서버와 통신하는 곳(middleware), 상태값을 변경하는 곳(extraReducers)를 구별하여 사용할 수 있습니다.