fetch와 localStorage의 조합

Steve·2022년 3월 3일
0
post-custom-banner

fetch 가져온것을 local에 담는게 너무 안됐었다.
분명 각각에 대한 이론들을 다 알고 있는데.

근데 정확히 아는게 아니였다. 왜 써야하는지를 알고 쓴것이 아닌
"남들 다 쓰자나?"
하고 썼었던..

import React, { useEffect, useState } from "react";
import axios from "axios";
import Recipe from "./Recipe";

function App() {
  const APP_ID = "c864dcc2";
  const APP_KEY = "95406cccd0f1dfef0af8f69c86297d1c";

  const [search, setSearch] = useState(""); // 검색한 단어를 인식하기 위한 state
  const [recipes, setrecipes] = useState( // map 돌리기 위한 state
    localStorage.getItem("watched")
      ? JSON.parse(localStorage.getItem("watched"))
      : []
  );

  const [query, setQuery] = useState(
    localStorage.getItem("watched")
      ? JSON.parse(localStorage.getItem("watched"))
      : "chicken"
  );

  // 최초 아무것도 없을 대 시행하기 위한 useEffect
  useEffect(() => {
    if (localStorage.getItem("watched") == null) {
      console.log("localStorage에 아무것도 없으면 출력되는 줄");
      getRecipes();
    }
  }, []);

  const inputHandler = (e) => {
    setSearch(e.target.value);
  };

  const clickHandler = (e) => {
    e.preventDefault();
    setQuery(search);
    getRecipes(search);
    setSearch("");
  };

  // await을 써주니 Promise 가 반환안되고 객체가 반환됨.
  // const data = await response.json();
  // 값이 들어올지 모르므로 async await을 통해 받아주자.
  // async await 쓰는이유 : 비동기코드를 동기적인 것처럼 읽기 쉽게 만들기위하여.

  const getRecipes = async (id) => {
    const response = await axios.get(
      `https://api.edamam.com/search?q=${
        id ? id : query // 최초 아무것도 검색하지 않았을 땐, query의 초기값인 chicken을 가져오고, 그 뒤론 가장 최근 검색한 것을 id로 받아서 local에 저장해준다.
      }&app_id=${APP_ID}&app_key=${APP_KEY}`
    );
    localStorage.setItem("watched", JSON.stringify(response.data.hits));
    setrecipes(JSON.parse(localStorage.getItem("watched")));
  };

  return (
    <div className="App">
      {/* onClick={clickHandler}과의 차이: input창 클릭만해도 빈화면이 나옴 */}
      <form className="search-form" onSubmit={clickHandler}>
        <input
          className="search-bar"
          type="text"
          onChange={inputHandler}
          value={search}
        />
        <button className="search-button" type="submit">
          Search
        </button>
      </form>
      <div className="recipes">
        
        {recipes.map((recipe, idx) => ( // 중괄호 아니고 소괄호로
          <Recipe
            key={idx}
            img={recipe.recipe.image}
            calories={recipe.recipe.calories}
            title={recipe.recipe.label}
            ingredients={recipe.recipe.ingredients}
          />
        ))}
      </div>
    </div>
  );
}

export default App;
profile
Front-Dev
post-custom-banner

0개의 댓글