How to use Redux-toolkit

이지·2021년 7월 19일
0

React

목록 보기
6/7
post-thumbnail

상태관리를 위해 redux를, 비동기 통신을위한 미들웨어 (redux-saga, redux-thunk) 를 고민하던 중, thunk를 내장 하되 보다 편리한 사용환경을 제공하는 redux-toolkit 을 도입하기로 했다. 간단한 사용법에 대해 알아보자.

0. axios customization

const instance = axios.create({
  //// Option 1 : localhost
  baseURL: "http://localhost:8080/", // jay 
  // Option 2 : fixed ip of backend local
  // baseURL: "http://ipaddress:8080/",
  //// Option 3 : backend server url
  // baseURL: "https://www.google.com/api",
  timeout: 3000,
});

export default instance;

먼저 통신을 위한 axios 를 커스텀 하여 사용했다. 서버 배포이전엔 백엔드 로컬 주소를 사용했고, 나중에는 백엔드로직을 다운받아서 내 로컬에서 사용했기 때문에 3가지 option을 번갈아가면서 썼다. baseurl만 스위치 해주면 custom instance 의 모든 주소가 일괄 변경되어 편리했다. 통신이 너무 길어지는 것을 방지하기 위해 3초가 지나면 timeout 하도록 했다.

1. api 통신 로직의 모듈화

analytics 관련 data 를 예시로 가져와 보겠다. 폴더구조는 다음과 같다.

utils < api < analytics

import axios from "utils/axiosConfig";

export const getAnalytics = async () => {
  //the reason I made dataArr is because I failed to return data during axios 
  const dataArr = [];
  await axios.get("/api/analytics").then((data: any) => {
    dataArr.push(data.data);
  });
  return dataArr;

2. slices logic


// Define a type for the slice state
interface ErrorMessage 
  errorMessage: string;
}

// Define a type of the report state
interface AnalyticsState {
  error: null | string;
  loading: boolean;
  // allPages: AnalyticsValueState[];
  allPages: AnalyticsValueState[];
}

//Define detail of analyticsValueState
interface AnalyticsValueState {
  users: number;
  points: number;
  materialTypes: {
    [key: string]: number;
  }; 
}

//initial state
const initialState: AnalyticsState = {
  error: null,
  loading: false,
  allPages: [],
};


//createAsyncThunk
//redux toolkit 에 내장된 createAsyncThunk을 활용하여, 비동기 통신 처리를 위한 세팅을 마친다. 

export const fetchAnalytics = createAsyncThunk<
  AnalyticsValueState[], // return type if it's fulfilled
  string, // type of arg
  { rejectValue: ErrorMessage }// error 발생시 return 값
>("analytics/fetch"//action , async (arg, thunkAPI) => {
  try {
    return await getAnalytics(); // 요기에 비동기 통신로직을 넣음 
  } catch (e) {
    return thunkAPI.rejectWithValue({
      errorMessage: e.message,
    });
  }
});

//위와 같이 createAsyncThunk 를 선언하게 되면 첫번째 파라미터로 선언한 액션 이름에 pending, fulfilled, rejected 의 상태에 대한 action 을 자동으로 생성해주게 됩니다. 

export const analyticsSlice = createSlice({
  name: "analytics",
  // `createSlice` will infer the state type from the `initialState` argument
  initialState,
  reducers: {
    //this will be exported to independant action for state changing
  },

  
  extraReducers: {
    [fetchAnalytics.pending.type]: (state) => { //호출전
      state.error = null;
      state.loading = true;
    },
    [fetchAnalytics.fulfilled.type]: (state, { payload }) => {// 성공

      state.error = null;
      state.loading = false;
      state.allPages = payload;
    },
    [fetchAnalytics.rejected.type]: (state, { payload }) => {//실패
      if (payload) state.error = payload.errorMessage;
      state.loading = false;
    },
  },
});

3. rootReducer, store, index.tsx


//rootReducer.ts

//slice들을 합쳐준다. 
const rootReducer = combineReducers({analyticSlice, ... })

                                     
//index.ts
                                     
// 합쳐진 rootreducer 를 store 에 담는다. 
const store = configureStore({
  reducer: rootReducer
});

//store의 state에 접근하는 useSelector 
export const useSelector: TypedUseSelectorHook<RootState> = useReduxSelector;
//action 전달함수 useDispatch
export const useDispatch = () => useReduxDispatch<AppDispatch>();

//index.tsx
import { Provider as ReduxProvider } from "react-redux";

//provider를 통해 app 전역해서 store 에 접근할 수 있게 한다. 
ReactDOM.render(
  <ReduxProvider store={store}>
  	  <App />
  </ReduxProvider>)
  

참고: https://redux-toolkit.js.org/usage/usage-guide

redux-toolkit 을 사용해 redux 작성 하기 (createAction, createReducer, createSlice, createAsyncThunk)

Redux-toolkit을 활용한 상태관리 [1]

Modern React Redux Toolkit - Login & User Registration Tutorial and Example

profile
이지피지레몬스퀴지🍋

0개의 댓글