JS 11 - Build a Recipe App With React

By Sheldon L Published at 2020-03-13 Updated at 2020-03-13


Operations

npx create-react-app recipe
cd recipe
npm start
import React, { useEffect, useState } from 'react';

import './App.css';

import Recipe from './Recipe';


const App = () => {


  // EDAMAM API
  const APP_ID = 'ec55aeb1';
  const APP_KEY = '46dd6bfebc7ca4806ab8fbb607fae1f7';

  const [recipes, setRecipes] = useState([]);
  const [search, setSearch] = useState('');
  const [query, setQuery] = useState('vegan');

  useEffect (() => { getRecipes() }, [query])  // run every time when the element in [] changes, if empty [], only run once it is mounted

  const getRecipes = async () => {
    const response = await fetch(
      `https://api.edamam.com/search?q=${query}&vegan&app_id=${APP_ID}&app_key=${APP_KEY}`
    )
    const data = await response.json();  // use `await` or `.then` every time use promit
    setRecipes(data.hits);
    console.log(data.hits)
  }

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

  const getSearch = e => {
    e.preventDefault();
    setQuery(search);
  }

  return(
    <div className="App">
      <form className="search-form" onSubmit={getSearch}>
        <input className="search-bar" type="text" value={search} onChange={updateSearch} />
        <button className="search-button" type="submit">
          Search
        </button>
      </form>

      <div className="Recipes">
        {recipes.map(recipe => (
          <Recipe
            key={recipe.recipe.label}
            title={recipe.recipe.label}
            calories={recipe.recipe.calories}
            image={recipe.recipe.image}
            ingredients={recipe.recipe.ingredients}
          />
        ))}
      </div>

    </div>
  );
}

export default App;
import React from 'react';
import style from './Recipe.module.css';


const Recipe = ({ title, calories, image, ingredients }) => {
  return(
    <div className={style.Recipe}>
      <h1>{title}</h1>
      <ul>
        {ingredients.map(ingredient => (
          <li>
            {ingredient.text}
          </li>
        ))}
      </ul>
      <p>Calories: {calories}</p>
      <img src={image} alt="" />
    </div>
  )
}

export default Recipe
.Recipe {
  border-radius: 10px;
  box-shadow: 0px 5px 20px rgb(71,71,71);
  margin: 20px;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  background: white;
  align-items: center;
  width: 700px;
  min-width: 40%;
}

.Recipe h1 {
  margin: 5px;
  padding: 5% 10%;
  overflow-wrap: normal;
}

.Recipe img {
  border-radius: 20%;
  width: 200px;
  margin: 5% 20%;
}