React에서 검색 창을 만드는 방법

내가 현재 관심이 있었던 것 중 하나는 검색 창을 만드는 것이지만 프론트엔드에서 이미 사용할 수 있는 것을 검색하고 싶지 않았습니다. 같은 방식으로 버튼을 클릭하여 Api에 요청하고 싶지 않았습니다.

저는 그냥 Input을 사용하고 싶었고, 작성을 마치자마자 자동으로 Api에 요청을 했고, 이것이 오늘 예제의 과제가 있는 곳입니다.

오늘 예제의 아이디어는 Game of Thrones에 나오는 집의 이름을 쓴 다음 가족 이름과 그 구성원을 나열하는 것입니다.

코딩하자



오늘의 예에서는 axios를 설치하여 애플리케이션에 대한 http 요청을 만들 것입니다.

npm i axios

create-react-app , vite 또는 기타를 사용하든 어쨌든 작동하기 때문에 애플리케이션 스캐폴드는 사용자에게 달려 있습니다.

먼저 axios 인스턴스를 만든 다음 Game Of Thrones Quotes API 을 사용합니다.

// @src/api/got.js

import axios from "axios";

export default axios.create({
  baseURL: "https://game-of-thrones-quotes.herokuapp.com/v1/house",
});


그런 다음 사용자 정의 후크 작업을 시작할 수 있습니다. 이 작업을 수행하기 위해 우리는 여러분이 잘 알고 있는 useState()useEffect() 두 개의 잘 알려진 후크를 사용할 것입니다. axios 인스턴스를 가져오는 것처럼.

// @src/hooks/useFetch.js

import { useState, useEffect } from "react";

import got from "../api/got";

const useFetch = () => {
  // ...
  return;
};

export default useFetch;


이 예제에서는 두 개의 속성을 가진 객체가 될 상태를 만드는 것으로 시작하겠습니다. 검색 용어가 될 slug 가 있습니다. 이것은 집의 이름입니다. 그리고 두 번째는 Api의 응답results입니다.

// @src/hooks/useFetch.js

import { useState, useEffect } from "react";

import got from "../api/got";

const useFetch = () => {
  const [data, setData] = useState({
    slug: "",
    results: [],
  });
  // ...
  return;
};

export default useFetch;


이제 슬러그가 변경될 때마다 실행되는 useEffect() 를 사용할 수 있습니다. 이 방법:

// @src/hooks/useFetch.js

import { useState, useEffect } from "react";

import got from "../api/got";

const useFetch = () => {
  const [data, setData] = useState({
    slug: "",
    results: [],
  });

  useEffect(() => {
    // ...
  }, [data.slug]);

  return;
};

export default useFetch;


그러나 이미 생각했을 수도 있습니다. 이제 useEffect() 내부에서 http 요청을 하면 사용자가 새 문자를 작성할 때마다 Api에 새 요청을 하게 됩니다.

그러나 우리는 그것을 원하지 않으므로 setTimeout() 를 사용할 것입니다. 왜냐하면 우리는 사용자가 작성을 마치자마자 http 요청이 완료되기를 원하기 때문에 1초의 시간 초과가 있을 것이기 때문입니다.

그러나 우리는 위험을 감수하게 될 것이고, 결국 몇 번의 시간 초과를 겪게 될 것이고 우리는 그것을 원하지 않을 것입니다. 타임아웃이 시작되고 사용자가 다시 쓰기를 하면 이전 타임아웃을 취소하고 싶기 때문이다. 따라서 useEffect()를 정리해야 하며 clearTimeout()를 사용하여 이전 시간 초과를 취소합니다. 이와 같이:

// @src/hooks/useFetch.js

import { useState, useEffect } from "react";

import got from "../api/got";

const useFetch = () => {
  const [data, setData] = useState({
    slug: "",
    results: [],
  });

  useEffect(() => {
    if (data.slug !== "") {
      const timeoutId = setTimeout(() => {
        // ...
      }, 1000);
      return () => clearTimeout(timeoutId);
    }
  }, [data.slug]);

  return;
};

export default useFetch;


이제 axios 인스턴스를 사용하여 http 요청을 할 수 있고 유일한 매개변수로 slug를 전달해 보겠습니다. 그런 다음 응답 데이터를 상태에 저장합니다.

// @src/hooks/useFetch.js

import { useState, useEffect } from "react";

import got from "../api/got";

const useFetch = () => {
  const [data, setData] = useState({
    slug: "",
    results: [],
  });

  useEffect(() => {
    if (data.slug !== "") {
      const timeoutId = setTimeout(() => {
        const fetch = async () => {
          try {
            const res = await got.get(`/${data.slug}`);
            setData({ ...data, results: res.data });
          } catch (err) {
            console.error(err);
          }
        };
        fetch();
      }, 1000);
      return () => clearTimeout(timeoutId);
    }
  }, [data.slug]);

  return;
};

export default useFetch;


이제 커스텀 훅을 사용할 수 있도록 state와 setter를 반환하면 됩니다.

// @src/hooks/useFetch.js

import { useState, useEffect } from "react";

import got from "../api/got";

const useFetch = () => {
  const [data, setData] = useState({
    slug: "",
    results: [],
  });

  useEffect(() => {
    if (data.slug !== "") {
      const timeoutId = setTimeout(() => {
        const fetch = async () => {
          try {
            const res = await got.get(`/${data.slug}`);
            setData({ ...data, results: res.data });
          } catch (err) {
            console.error(err);
          }
        };
        fetch();
      }, 1000);
      return () => clearTimeout(timeoutId);
    }
  }, [data.slug]);

  return { data, setData };
};

export default useFetch;


이제 UI를 생성하여 시작할 수 있습니다. 먼저 App.jsx 부터 시작하겠습니다. 마찬가지로 사용자 지정 후크를 가져오고 House.jsx 구성 요소(아직 생성되지 않음)를 가져오고 조건부 렌더링을 수행합니다. 집 데이터가 있는 경우에만 표시할 것이기 때문입니다.

// @src/App.jsx

import React from "react";

import useFetch from "./hooks/useFetch";
import House from "./components/House";

export default function App() {
  const { data, setData } = useFetch();
  return (
    <main>
      <input
        type="text"
        placeholder="Type your favorite house"
        value={data.slug}
        onChange={(e) => setData({ ...data, slug: e.target.value })}
      />
      <br />
      {data.results.length > 0 ? <House family={data.results[0]} /> : null}
    </main>
  );
}


이제 House.jsx 구성 요소 생성을 시작할 수 있으며 동일한 구성 요소에서 Members.jsx (아직 생성되지 않음)을 가져올 것입니다.

// @src/components/House.jsx

import React from "react";

import Members from "./Members";

export default function House({ family }) {
  return (
    <div>
      <h1>{family.name}</h1>
      <Members members={family.members} />
    </div>
  );
}


마지막으로 각 가족 구성원을 나열할 마지막 구성 요소를 만들 수 있습니다.

// @src/components/Members.jsx

import React from "react";

export default function Members({ members }) {
  return (
    <ul>
      {members.map((el, i) => (
        <li key={i}>{el.name}</li>
      ))}
    </ul>
  );
}


다음과 유사한 결과를 얻어야 합니다.



결론



항상 그렇듯이 흥미롭게 보셨기를 바랍니다. 이 기사에서 오류를 발견했다면 댓글에 언급해 주세요. 🪗

좋은 하루 되세요! 👋 😜

좋은 웹페이지 즐겨찾기