[React js] useReducer, useAsync(커스텀훅)

seokki kwon·2022년 9월 20일
0

useReducer 를 사용하여 요청 상태관리

reducer

// LOADING, SUCCESS, ERROR
export function asyncReducer(state, action) {
  switch (action.type) {
    case "LOADING":
      return {
        loading: true,
        data: null,
        error: null,
      };
    case "SUCCES":
      return {
        loading: false,
        data: action.data,
        error: null,
      };
    case "ERROR":
      return {
        loading: false,
        data: null,
        error: action.error,
      };
    default:
      throw new Error(`Unhandled action type: ${action.type}`);
  }
}

api

  const fetchUsers = async () => {
    dispatch({ type: "LOADING" });
    try {
      const response = await axios.get(
        "https://jsonplaceholder.typicode.com/users"
      );
      dispatch({ type: "SUCCES", data: response.data });
    } catch (e) {
      dispatch({ type: "ERROR", error: e });
    }
  };

reduer 를 사용하여 요청상태를 관리가능

사용

const [state, dispatch] = (reducer, initialstate)

reducer 의 장점

  • 로직분리 가능
  • dispatch 로 간단하게 상태를 전송하고 받아옴

커스텀훅

import { useReducer, useEffect, useCallback } from "react";

// LOADING, SUCCESS, ERROR 요청 상태를 반홚하는 리듀서
export function asyncReducer(state, action) {
  switch (action.type) {
    case "LOADING":
      return {
        loading: true,
        data: null,
        error: null,
      };
    case "SUCCES":
      return {
        loading: false,
        data: action.data,
        error: null,
      };
    case "ERROR":
      return {
        loading: false,
        data: null,
        error: action.error,
      };
    default:
      throw new Error(`Unhandled action type: ${action.type}`);
  }
}

function useAsync(cb, deps = [], skip = false) {
  const [state, dispatch] = useReducer(asyncReducer, {
    loading: false,
    data: null,
    error: null,
  });
 // 콜백함수를 받아서 결과값을 리듀서로 전달
  const fetchData = useCallback(async () => {
    dispatch({ type: "LOADING" });
    try {
      const data = await cb();
      dispatch({ type: "SUCCES", data });
    } catch (error) {
      dispatch({ type: "ERROR", error });
    }
  }, [cb]);

  useEffect(() => {
    if (!skip) {
      return;
    }
    fetchData();
    // eslint-disable-next-line
  }, deps);

  return [state, fetchData];
}

export default useAsync;

요청하는 API 함수

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

커스텀훅을 사용하여 통신을 관리하면 여러곳에서 사용가능

  • 콜백함수, 의존배열, 기타등등 파라미터를 받는다.
  • 콜백함수를 실행하고 요청의 상태를 리듀서를 거쳐서 반환받는다.
  • 데이터를 요청하는 함수또한 반환받는다

한번 구성이 어렵더라도 여러곳에서 사용이 가능하기에 재사용성이 좋다.

profile
웹 & 앱개발 기록

0개의 댓글