0

I would like to delete a search result by clicking on the X icon on the individual card.

The search returns 10 recipes from the API, generating 10 divs. How would I go about removing individual divs onClick of the icon whilst keeping the other divs? Essentially just a remove search result button.

return (
    <div className='App'>
      <form onSubmit={getSearch} className="search-form">
        <InputGroup>
          <InputGroupAddon addonType="prepend">
            <InputGroupText><FontAwesomeIcon icon={faSearch} /></InputGroupText>
          </InputGroupAddon>
          <Input className="search-bar" type="text" placeholder="Search for recipe..." value={search} onChange={updateSearch} />
        </InputGroup>
        <Button color="primary" size="sm" className="search-button" type="submit">Search</Button>
      </form>
      <div className="recipes">
        {recipes.map(recipe => (
          <Recipe
            key={recipe.recipe.label}
            title={recipe.recipe.label}
            theUrl={recipe.recipe.url}
            image={recipe.recipe.image}
            ingredients={recipe.recipe.ingredients}
            source={recipe.recipe.source}
            healthLabels={recipe.recipe.healthLabels}
            servings={recipe.recipe.yield} />
        ))}
      </div>
    </div>

enter image description here

const Recipe = ({ title, theUrl, image, ingredients, source, healthLabels, servings }) => {
    return (
        <div className={style.recipe}>
            <FontAwesomeIcon className={style.delete} icon={faTimes} />
            <h3 >{title}</h3>
            <Badge className={style.badge} color="primary">{source}</Badge>
            <p>Serves: <Badge color="primary" pill>{servings}</Badge></p>
            <img src={image} alt='food' />
            <ol className={style.allergens}>
                {healthLabels.map(healthLabel => (
                    <li>{healthLabel}</li>
                ))}
            </ol>
            <div className={style.ingr}>
                <ol>
                    {ingredients.map(ingredient => (
                        <li>{ingredient.text}</li>
                    ))}
                </ol>
                <Button className={style.button} outline color="primary" size="sm" href={theUrl} target="_blank">Method</Button>
            </div>
            <div className={style.info}>
                <div className={style.share}>
                    <WhatsappShareButton url={theUrl}><WhatsappIcon round={true} size={20} /></WhatsappShareButton>
                    <FacebookShareButton url={theUrl}><FacebookIcon round={true} size={20} /></FacebookShareButton>
                    <EmailShareButton url={theUrl}><EmailIcon round={true} size={20} /></EmailShareButton>
                </div>
            </div>
        </div>

    );
}

enter image description here

1
  • Could you make it an online demo so we can make the fix very quick! Commented Apr 2, 2020 at 11:04

2 Answers 2

1

Simply update the recipes array and React will update the HTML.

I'm not sure where recipes comes from, but if you set an onClick on, say, <Recipe label="x"> that deletes the corresponding recipe element from recipes, then React should no longer render that recipe.

Sign up to request clarification or add additional context in comments.

Comments

1

That should be easy. Here's one way:

add onClick to this

<FontAwesomeIcon onClick={deleteRecipe} className={style.delete} icon={faTimes} />

pass a reference of the function that deletes the recipe.

deleteRecipeHandler = (id) => {
 // filter your recipes here such that the new recipes array doesn't contain the recipe
 // with the id you're getting here.

 // Change the below code how you need
   const newRecipes = oldRecipes.filter(recipe => {
     return recipe.id !== id;
   });
}

{recipes.map(recipe => (
          <Recipe
            key={recipe.recipe.label}
            deleteRecipe={this.deleteRecipeHandler.bind(this,recipe.recipe.id)}
            title={recipe.recipe.label}
            theUrl={recipe.recipe.url}
            image={recipe.recipe.image}
            ingredients={recipe.recipe.ingredients}
            source={recipe.recipe.source}
            healthLabels={recipe.recipe.healthLabels}
            servings={recipe.recipe.yield} />
        ))}

since you're destructuring your props you can use

const Recipe = ({ title, theUrl, image, ingredients, source, healthLabels, servings, deleteRecipe }) => {
    return (
        <div className={style.recipe}>
            <FontAwesomeIcon onClick={deleteRecipe} className={style.delete} icon={faTimes} />

3 Comments

Hey! Thanks for your answer. What do you mean here: // filter your recipes here such that the new recipes array doesn't contain the recipe // with the id you're getting here.
I meant to update your recipes array. Wait, I'll update my answer.
useEffect(() => { getRecipes(); }, [query]) const getRecipes = async () => { const response = await fetch(api.edamam.com/search?q=${query}&app_id=${APP_ID}&app_key=${APP_KEY}&from=0&to=10&calories=591-722&health=alcohol-free) const data = await response.json(); setRecipes(data.hits); } const updateSearch = e => { setSearch(e.target.value); } const getSearch = e => { e.preventDefault(); setQuery(search); setSearch(''); }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.