My Cook Book
Published: 2022-02-08 23:15:45

For my phase 2 project with Flatiron school I decided to make a cook book to store some of my favorite recipes, and some new ones that I would like to try. This web application was written with React, and this is my first React project. I had a lot of fun working on this project. The major features of this project are the list of recipes that can be filtered in to category's,
![list of recipes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4dks5q9rjrf4zuc70ds.jpg)
and a form to add new recipes to the database.
![new recipe form](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3tydhux43k0ofkcfirte.jpg)
On the list of recipes you can click on one to see the full recipe.
![full recipe](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/00gg7rm9usthplta1dxw.jpg)
One piece of code that was both challenging, and a lot of fun to work on was the filter. First I had to create a dropdown to select a category.
```
<div id="category-filter">
  <label htmlFor="category">Filter By: </label>
  <select name="category">
    <option value="all">Choose a Category...</option>
    <option value="appetizers">Appetizers</option>
    <option value="beverages">Beverages</option>
    <option value="breakfast">Breakfast</option>
    <option value="desserts">Desserts</option>
    <option value="main dishes">Main Dishes</option>
    <option value="salads">Salads</option>
    <option value="side dishes">Side Dishes</option>
    <option value="soups and stews">Soups and Stews</option>
  </select>
</div>
```
After That I had to control the form in state so I could access the value later.
```
// the recipes prop is a list of recipes from an api
function RecipePage({ recipes }) {

  {/* here I set the initial state */}
  const [filterBy, setFilterBy] = useState("all")

  <div>
    <label htmlFor="category">Filter By: </label>

    {/* now I can set the value and onChange */}
    <select
      name="category"
      value={filterBy}
      onChange={e => setFilterBy(e.target.value)}
    >
      {/* ...
      options
      ... */}
    </select>
    {/* pass recipes and filterBy in to RecipeList */}
    <RecipeList recipes={recipes} filterBy={filterBy} />
  </div>
}
```
Now that I have the value of the dropdown stored in state as `filterby`, I can pass that value in to `RecipeList`. In `RecipeList` we receive two props, recipes, the list of recipes, and `filterBy`, the selected category on the dropdown. For recipes, I don't want to alter it (I'll need the original list later) so I create a new variable in state, `filteredRecipes`. Next, I filter through the list of recipes and find all of the recipes that match the currently selected category. Then, I save those recipes to `filteredRecipes` so I can re-render the list with just the selected recipes.

```
function RecipeList({ recipes, filterBy }) {
  // set new state variable
  const [filteredRecipes, setFilteredRecipes] = useState([])

  //This is a side effect that runs everytime filterBy changes
  useEffect(() => {
    if (filterBy === "all") {
      setFilteredRecipes(recipes)
    } else {

      // first, I create a new array
      let newFilteredRecipes = []

      // next I filter through the list
      recipes.filter(recipe => {

        // if the category's match, 
        if (recipe.category === filterBy) {

          // add the recipe to the array
          newFilteredRecipes.push(recipe)
        }
      })
      // set the new filtered list to filteredRecipes
      setFilteredRecipes(newFilteredRecipes)
    }
  }, [filterBy])

  // now the JSX has filtered recipes to work with
  return (
    <div>
      {filteredRecipes.length !== 0 &&
        filteredRecipes.map(recipe => (
          <RecipeListing key={recipe.id} recipe={recipe} />
        ))
      }
    </div>
  )
}
```
In conclusion, I created a dropdown, and I controlled the dropdown in state. Then, I compared each recipes category to the value in state. Lastly, I stored the new list of filtered recipes in it's own state variable as to not alter the original list and to re-render the filtered list.