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.