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,

and a form to add new recipes to the database.

On the list of recipes you can click on one to see the full recipe.

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.
              
    
Top comments (1)
Thank you. I really appreciate that.