[패스트캠퍼스 수강 후기] 프론트엔드 인강 100% 환급 챌린지 42회차 미션 - 33강 Context에서 비동기작업 상태관리 - 리팩토링 및 정리

2 minute read

반복되는 코드를 줄이자!

우리가 작성했었던 usersContext의 반복되는 코드들을 줄여볼 것이다.

api.js

import axios from "axios";

export async function getUsers() {
  const response = await axios.get(
    "https://jsonplaceholder.typicode.com/users"
  );
  return response.data;
}

export async function getUser(id) {
  const response = await axios.get(
    `https://jsonplaceholder.typicode.com/users/${id}`
  );
  return response.data;
}

asyncActionUtils.js

export function createAsyncDispatcher(type, promiseFn) {
  const SUCCESS = `${type}_SUCCESS`;
  const ERROR = `${type}_ERROR`;

  async function actionHandler(dispatch, ...rest) {
    dispatch({ type });
    try {
      const data = await promiseFn(...rest);
      dispatch({
        type: SUCCESS,
        data,
      });
    } catch (e) {
      dispatch({
        type: ERROR,
        error: e,
      });
    }
  }
  return actionHandler;
}

export const initialAsyncState = {
  loading: false,
  data: null,
  error: null,
};

const loadingState = {
  loading: true,
  data: null,
  error: null,
};

const success = (data) => ({
  loading: false,
  data,
  error: null,
});
const error = (e) => ({
  loading: false,
  data: null,
  error: e,
});

export function createAsyncHandler(type, key) {
  const SUCCESS = `${type}_SUCCESS`;
  const ERROR = `${type}_ERROR`;

  function handler(state, action) {
    switch (action.type) {
      case type:
        return {
          ...state,
          [key]: loadingState,
        };
      case SUCCESS:
        return {
          ...state,
          [key]: success(action.data),
        };
      case ERROR:
        return {
          ...state,
          [key]: error(action.error),
        };
      default:
        return state;
    }
  }
  return handler;
}

UserContext.js

import React, { createContext, useReducer, useContext } from "react";
import {
  createAsyncDispatcher,
  createAsyncHandler,
  initialAsyncState,
} from "./asyncActionUtils";
import * as api from "./api"; //api안의 모든 객체 불러옴

const initialState = {
  users: initialAsyncState,
  user: initialAsyncState,
};

// GET_USERS
// GET_USERS_SUCCESS
// GET_USERS_ERROR
// GET_USER
// GET_USER_SUCCESS
// GET_USER_ERROR

const usersHandler = createAsyncHandler("GET_USERS", "users");
const userHandler = createAsyncHandler("GET_USER", "user");

function usersReducer(state, action) {
  switch (action.type) {
    case "GET_USERS":
    case "GET_USERS_SUCCESS":
    case "GET_USERS_ERROR":
      return usersHandler(state, action);
    case "GET_USER":
    case "GET_USER_SUCCESS":
    case "GET_USER_ERROR":
      return userHandler(state, action);

    default:
      throw new Error("Unhandled action type", action.type);
  }
}

const UsersStateContext = createContext(null);
const UsersDispatchContext = createContext(null);

export function UsersProvider({ children }) {
  const [state, dispatch] = useReducer(usersReducer, initialState);
  return (
    <UsersStateContext.Provider value={state}>
      <UsersDispatchContext.Provider value={dispatch}>
        {children}
      </UsersDispatchContext.Provider>
    </UsersStateContext.Provider>
  );
}

export function useUsersState() {
  const state = useContext(UsersStateContext);
  if (!state) {
    throw new Error("Cannot find UserProvider");
  }
  return state;
}

export function useUsersDispatch() {
  const dispatch = useContext(UsersDispatchContext);
  if (!dispatch) {
    throw new Error("Cannot find UserProvider");
  }
  return dispatch;
}

export const getUsers = createAsyncDispatcher("GET_USERS", api.getUsers);
export const getUser = createAsyncDispatcher("GET_USER", api.getUser);

솔직히 뭐하는건지 하나도 모르겠다..ㅎㅎㅎ
비전공자 위주로 알려준다더니 혼자서 그냥 쭉쭉 쓰고 뭐 설명도 없고 진도만 쭉쭉 나가는데 전공자들은 다 제대로 알아듣는걸까? 내가 비전공자라 그런건가? 벨로퍼트 홈페이지에 댓글 보니까 나같은 사람이 한둘이 아니던데.. 어떤 사람들은 구글링하라고 한다. 아니 내가 구글링 할꺼면 뭣하러 내돈주고 결제해서 이 영상을 굳이 보고 있는가? 그냥 벨로퍼트 홈피 뒤져서 독학하는거랑 뭐가 다른거지?
아무튼 답답한 마음에 몇자 찌끄려봤는데 돈은 이미 나간거고 진짜 댓글들 말들로 발품 팔아서 부족한 지식 채워보는 수밖에.. 패스트캠퍼스 제발 광고할때 비전공자도 쉽게 배울 수 있다느니 어쩐다느니 이런 소리는 좀 안했으면 좋겠다^^..

오늘은 여기까지..
시청 영상 33강 07~08까지
수강인증이미지 수강인증이미지 수강인증이미지 프론트엔드 개발 올인원 패키지 with React Online. 👉 https://bit.ly/31Cf1hp

Comments