크게 4가지 파트로 나뉠 수 있습니다
1. import
2. 변수 선언
3. 함수 선언
4 JSX 문법

import './App.css';
import React, { useEffect, useState } from "react"; //react 내장함수 useEffect,useState를 사용하겠다 선언
import Recipe from './Recipe'; //Recipe import 

./App.css import 합니다, 내장함수 useEffect, useState 를 호출합니다, ./Recipe 를 호출합니다

  const APP_ID = "2b215e76bde";
  const APP_KEY = "ec75e604b3fcb19322b51f9ed9bc9906bcc";
  const [recipes, setRecipes] = useState([]);// recipes 초기화, 아무값 들어 있지 않습니다
  const [search, setSearch] = useState('');//search 초기화, 아무값 들어 있지 않습니다.
  const [query, setQuery] = useState('chicken'); //query 초기화, chicken 이 들어 있습니다
  //useEffect 는 웹브라우저가 재랜더링 할때마다 실행됩니다 -> 안좋음
  //useEffect 에 dependency ([]) 를 추가해서 웹 브라우저 실행시 단 한번만 실행되게 합니다
  //useEffect 에 [변수] 를 넣어서, 변수가 바뀔때마다 재 랜더링이 실행되게 합니다

api id 랑 key 는 유효하지 않습니다. 변수 선언 파트 입니다, recipes랑 search 가 초기값이 없는 이유
1. recipes 는 setRecipes의 인자값을 recipes 에 넣습니다. 그 인자값은 api로 가져온 데이터 입니다. (getRecipes 에서 확인)
2. search 는 input 태그 text 입니다. 초기에 빈 값인데, 사용자가 글을 입력하면 value 로써 값이 던져집니다. (getSearch 에서 확인)

useEffect(() => {
    getRecipes(); //웹브라우저 실행시 최초 1회 실행됩니다
  }, [query]);//초기 query 는 chicken 입니다, 

  //비동기식을 동기식으로 바꾸다.
  //웹브라우저 실행때 한번, query -> 검색창에 입력되고 버튼을 누르고 나면 실행됩니다
  const getRecipes = async () => {
    const response = await fetch(`https://api.edamam.com/search?q=${query}&app_id=${APP_ID}&app_key=${APP_KEY}`); //웹 브라우저한테 api를 받을때까지 뒷 로직을 실행시키지 않게 시킵니다
    const data = await response.json(); //받은 데이터를 json 형태로 저장합니다
    //setRecipes 안에 넣음으로써 recipes 가 data.hits를 가지고 있다
    setRecipes(data.hits); //json 데이터에 hits 키값을 주고 value 를 가져옵니다
  }
  //input 태그에 입력된 인자값이 e 로 갑니다. setSearch 에 태그에 입력,삭제된 값들이 출력됩니다
  const updateSearch = e => {
    setSearch(e.target.value);//초기값이 없었던 search 가 e.target.value 로 채워집니다.

  }
  const getSearch = e => {//submit 버튼을 누르면 onSubmit 속성때문에 getSearch 함수가 실행됩니다. 받은 인자값에 페이지 이동을 하지 않기위해 preventDefault()가 있습니다
    e.preventDefault();
    setQuery(search);//초기 query 였던 chicken 이 검색에 따라 달라집니다 //search 는 input 의 value 입니다, 초기값 chicken 이  input 으로부터 들어온 value 로 채워집니다
    setSearch('');//검색 버튼을 한번 누르고 난뒤 입력한 값이 사라집니다
  }

함수 선언파트 입니다. useEffect 는 웹브라우저 실행시 최소 1번 실행으로 chicken 레시피가 호출됩니다. query 가 바귈때마다 레시피는 바귑니다. query 는 setQuery 의 인자값이 바뀔때 바귀는데 form 태그에서 버튼을 누르면 onSubmit 이 작동해서 getSearch 함수 호출됩니다.

<div className="App">
      {/* submit 버튼을 누를때 마다 onSubmit 에 있는 getSearch가 실행됩니다  onSubmit 은 호출 될때마다 웹 브라우저 새로고침이 발생하기 때문에 preventDefault 로 잡아줘야 합니다 */}
      <form onSubmit={getSearch} className="search-form">
        {/* input태그에 변화가 있을때마다(글자입력,삭제) updateSearch 함수가 실행됩니다 */}
        {/* 자바스크립트 값을 jsx 내부에서 사용할 때는 중괄호로 감싸주어야 한다 */}
        <input className="search-bar" type="text" value={search} onChange={updateSearch} />
        <button className="search-button" type="submit">Search</button>
      </form>
      {/* map 메소드는 recipes 로 받아온 모든 데이터를 배열"[]" 에 넣겠다 입니다  */}
      <div className="recipes">
        {recipes.map(recipe => (
          <Recipe
            //아랫 키 값들은 Recipe.js 로 가서 인자값이 됩니다 key 라는 유니크 값이 없다면 콘솔에 에러가 뜹니다(고유값 주라고 )
            key={recipe.recipe.label}
            title={recipe.recipe.label}
            calories={recipe.recipe.calories}
            image={recipe.recipe.image}
            ingredients={recipe.recipe.ingredients}
          />
        ))};
      </div>
    </div>

JSX 파트 입니다. 함수 호출 2군데 있고, 텍스트박스에 글을 입력하고 버튼을 누르면 다른 레시피를 찾습니다. 받아온 레시피를 재정렬 하기 위해서 map 메소드를 사용합니다. 해당 인자값recipe 은 Recipe.js 의 인자값으로 넘어 갑니다 key 가 없다면 콘솔창 워닝이 발생합니다. label 이 각 레시피의 고유값이라 넣었습니다. 아무 중복되지 않는 값만 넣는다면 워닝은 사라집니다

Recipe.js 파트 입니다

import React from 'react';
import style from './recipe.module.css';

const Recipe = ({ title, calories, image, ingredients }) => {
    return (
        <div className={style.recipe}>
            <h1>{title}</h1>
            <ol>
                {ingredients.map(ingredient => (
                    <li>{ingredient.text}</li>
                ))}
            </ol>
            <p>{calories}</p>
            <img className={style.image} src={image} alt="" />
        </div >
    );
}
export default Recipe;

넘어온 인자값이 보입니다. div className 에 recipe.module.css 로 스타일링 해서 넘겨 줬습니다. 넘어온 레시피는 map으로 재정렬 해서 번호를 매겨줬습니다.
{/ onChange 가 없으면 value 는 항상 empty 라서 input 태그에 글을 적을 수 없습니다 /}

profile
건물주가 되는 그날까지

0개의 댓글