๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Frontend/TypeScript

[ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ(TypeScript) ] customHooks๋กœ getApi hooks ๊ด€๋ฆฌํ•˜๊ธฐ

by YWTechIT 2021. 8. 18.
728x90

๐Ÿ“ customHooks๋กœ getApi ์ฝ”๋“œ ๊ด€๋ฆฌํ•˜๊ธฐ

fetch ํ˜น์€ axios๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ api๋ฅผ ๋ฐ›์•„์˜ฌ ๋•Œ ๊ธฐ์กด์—๋Š” app.tsx ํŒŒ์ผ ๋‚ด์—์„œ useEffect๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ api๋ฅผ ๋ฐ›์•„์˜ค๋Š” ์ฝ”๋“œ๋ฅผ ๋ชจ๋‘ ์ž‘์„ฑํ–ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, app.tsx์— api์™€ ๊ด€๋ จ๋œ ์ฝ”๋“œ๋ฅผ ๋ชจ๋‘ ์ž‘์„ฑํ•˜๋ฉด ๋‹ค๋ฅธ ๋กœ์ง์ฝ”๋“œ๋ฅผ ๋ณด๋Š”๋ฐ ์‹ ๊ฒฝ ์“ฐ์—ฌ์„œ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ ์˜ฎ๊ฒจ์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋– ์˜ฌ๋ž๊ณ  hooks ํด๋”๋ฅผ ์ƒ์„ฑํ•˜์—ฌ customHooks๋กœ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด app.tsx์˜ ๊ฐ€๋…์„ฑ์„ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

 

data, loading, error ๊ฐ’์„ export ํ•  ๋•Œ ํƒ€์ž…์ถ”๋ก ์ด ๋ช…ํ™•ํ•˜๊ฒŒ ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์–ด as๋ฌธ์„ ์‚ฌ์šฉํ•ด์„œ ์–ด๋–ค ํƒ€์ž…์ธ์ง€ ๋ช…์‹œํ–ˆ๋‹ค. as๋ฌธ ๋Œ€์‹  interface๋ฅผ usePosts ๋ฆฌํ„ด๊ฐ’์— ๋ถ™์—ฌ์ค˜๋„ ๋˜๋Š”๋ฐ ์ด๋•Œ๋Š” {}๋กœ return ํ•˜๊ณ  app.tsx์—์„œ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ๋„ {}๋กœ ๋ถˆ๋Ÿฌ์˜ค๋Š”๊ฒƒ์„ ์žŠ์ง€ ๋ง์ž.

 

์ž์„ธํ•œ ์ฝ”๋“œ๋Š” ๊นƒํ—ˆ๋ธŒ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š” :)

 

// hooks/usePosts/index.tsx
// use alias(as)
import axios, { AxiosResponse } from "axios";
import { useEffect, useState } from "react";
import { Data } from "../../types";

const usePosts = () => {
  const [data, setData] = useState<Data[]>([]);
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<Error>();

  useEffect(() => {
    setLoading(true);
    const getPosts = async () => {
      try {
        const response: AxiosResponse<any> = await axios.get(
          "https://jsonplaceholder.typicode.com/posts/"
        );
        setData(response.data);
        setLoading(false);
      } catch (e) {
        setError(e);
        setLoading(false);
      }
    };
    getPosts();
  }, []);

  return [data, loading, error] as [Data[], boolean, Error];
};

export default usePosts;

 

// hooks/usePosts/index.tsx
// use interface
import axios, { AxiosResponse } from "axios";
import { useEffect, useState } from "react";
import { Data } from "../../types";

interface Response {
  data: Data[];
  loading: boolean;
  error?: Error;
}

const usePosts = (): Response => {
  const [data, setData] = useState<Data[]>([]);
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<Error>();

  useEffect(() => {
    setLoading(true);
    const getPosts = async () => {
      try {
        const response: AxiosResponse<any> = await axios.get(
          "https://jsonplaceholder.typicode.com/posts/"
        );
        setData(response.data);
        setLoading(false);
      } catch (e) {
        setError(e);
        setLoading(false);
      }
    };
    getPosts();
  }, []);

  return {data, loading, error};
};

export default usePosts;

 

// app.tsx
import Container from "./components/container";
import Card from "./components/molecules/card";
import usePosts from "./hooks/useposts";

const App = () => {
  const [data, loading, error] = usePosts();

  if (loading) {
    return <div>loading...</div>;
  }

  if (error){
    return <div>Error...</div>
  }

  return (
    <Container>
      {data.map((item) => (
        <Card key={item.id} item={item}></Card>
      ))}
    </Container>
  );
};

export default App;

 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€