[WIL] redux/toolkit useNavigate

SaMag·2022년 5월 9일
0

redux/toolkit에서의 routing

redux, react-router-dom(v5)

기존에 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)
    })
  }
};

redux/toolkit, typescript, react-router-dom(v6)

하지만 프로젝트를 진행하며 개발단계에서 의도치 않은 에러를 없애고 성능의 향상을 위해 리덕스 툴킷, 타입스크립트, 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)를 구별하여 사용할 수 있습니다.

profile
개발자

0개의 댓글