【问题标题】:React: hide and show specific elements from array displayed using map()反应:隐藏和显示使用 map() 显示的数组中的特定元素
【发布时间】:2021-10-28 18:19:53
【问题描述】:

目标是显示一系列食谱。用户首先获得包含食谱名称、图片和一些基本信息(烹饪时间等)的可用食谱的总体概述。当用户单击按钮(显示完整配方)时,应显示完整配方。当用户点击一个新按钮(隐藏完整配方)时,完整的配方再次被隐藏,用户只能看到配方的总体概览。

目前,我已经创建了一组(两个)食谱。通过使用 map() 我返回了不同的食谱。但是,当单击显示或隐藏完整配方按钮时,会显示所有配方。如何确保当用户点击“显示完整食谱”时,他/她只能看到特定的食谱?

import React, { useState } from 'react';

var recipes = [{
                _id: 1,
                title: "Spaghetti",
                type: "Dinner or Lunch",
                category: "vegan",
                image: "http://via.placeholder.com/350x250",
                cookingTime: 35,
                ingredients: [[1, "onion"], [3, "tomato"], [1, "aubergine"], [1, "beans"], [1, "tomatoesauce"], [1, "tomatoconcentrate"], [1, "pepper"], [1, "salt"], [1, "pasta"]],
                cookingSteps: [["Boil a pot full of watter. Once the watter is boiling, add the pasta. The cooking time depends on the pasta."], ["Cut the onion and the garlic. Add them to a poth with olive oil. Cook for 2 to 3 minutes"], ["Cut the other vegetables. After the onion and the garlic are marrinated, add the different vegtables to the poth. Let them cook with the lid on for about 10 to 15 minutes or untill the vegetables are ready."], ["Once the vegetables are ready, add the tomato sauce and the tomato concentrate. Add the beans. Let this cook for another five minutes"], ["Remove the lid from the pot. Add pepper and salt and other additional spcices, like italian spcies or special peppers"]]
              },
              {
                _id: 2,
                title: "Eggs",
                type: "Breakfast",
                category: "vegan",
                image: "http://via.placeholder.com/350x250",
                cookingTime: 10,
                ingredients: [[4, "egg"], [1, "tomato"], [1, "pepper"], [1, "salt"]],
                cookingSteps: [["cut the tomato. Heat olive oil in a pan, add the tomato and bake it till the outer peal of the tomato gets soft. If you like pepper, it is adviced to first bake the pepper a bit in the pan"], ["Meanwhile, scrambel the eggs. Once the tomatoes are ready (see step 1), add the eggs"]]
              }
            ];


//TODO: make sure only one specific recipe shows when clicked
function DisplayRecipes(){
    //declare useState and onClick for button to show full recipe
    const[isNotDisplayed, isDisplayed] = React.useState(false)
    const onClickShow = () => {isDisplayed(true)};
    const onClickHIde = () => isDisplayed(false);


    //return statement to render recipe
    return(
        <div className="card-list">
            <div className="container">
                <h1 className="page-title">Our vegan recipes...</h1>
                <div className="row">
                    {
                        recipes.map((recipe)=>{
                            return(
                                <div key={recipe._id} className="col-md-3">
                                    <div className="card bwm-card">
                                        <div className="card-title">
                                            <h2>{recipe.title}</h2>
                                        </div>
                                        <img className="card-img-top" src={recipe.image} alt={recipe.title} />
                                        <div className="card-subtitle">
                                            <h3><b>Type: {recipe.type} </b></h3>
                                            <h3><b>Category: {recipe.category}</b></h3>
                                            <h3><b>Cooking time: {recipe.cookingTime} minutes</b></h3>
                                        </div>
                                        <div>
                                            { isNotDisplayed ? 
                                                    <div className="card-body">
                                                        <div className="card-body-ingredient">
                                                        {
                                                            recipe.ingredients.map((ingredient, i) =>{
                                                                return(
                                                                    <table>
                                                                        <tr>
                                                                            <th>Quantity</th>
                                                                            <th>Ingredient</th>
                                                                        </tr>
                                                                        <tr>
                                                                            <th>{ingredient[0]}</th>
                                                                            <th>{ingredient[1]}</th>
                                                                        </tr>
                                                                    </table>
                                                                )
                                                            })
                                                        }
                                                    </div>
                                                    <div className="card-body-cookingsteps">
                                                            {
                                                                recipe.cookingSteps.map((cookingstep, i) =>{
                                                                    return(
                                                                        <p>{cookingstep}</p>
                                                                    )
                                                                })
                                                            }
                                                    </div>
                                                        <div>
                                                            <button type="submit" value="Hide full recipe" onClick= {onClickHIde}>Hide full recipe</button>
                                                        </div>
                                                    </div>
                                                : 
                                                    <button type="submit" value="Show full recipe" onClick= {onClickShow}>Show full recipe</button>
                                            } 
                                        </div>
                                    </div>
                                </div>
                            )
                        })
                    } 
                </div>
            </div>
        </div>
    )
} 

export default DisplayRecipes;

提前谢谢你!

【问题讨论】:

  • 发布描述单一配方的代码

标签: javascript arrays reactjs


【解决方案1】:

每个配方都需要一个单独的状态。目前所有的菜谱共享相同的状态,所以当一个打开时,它们都是打开的。

分离状态的最佳方法是让每个配方都有自己的组件和自己的状态。

import React, {useState} from 'react';

const recipes = [
    {
        _id: 1,
        title: 'Spaghetti',
        type: 'Dinner or Lunch',
        category: 'vegan',
        image: 'http://via.placeholder.com/350x250',
        cookingTime: 35,
        ingredients: [
            [1, 'onion'],
            [3, 'tomato'],
            [1, 'aubergine'],
            [1, 'beans'],
            [1, 'tomatoesauce'],
            [1, 'tomatoconcentrate'],
            [1, 'pepper'],
            [1, 'salt'],
            [1, 'pasta'],
        ],
        cookingSteps: [
            [
                'Boil a pot full of watter. Once the watter is boiling, add the pasta. The cooking time depends on the pasta.',
            ],
            [
                'Cut the onion and the garlic. Add them to a poth with olive oil. Cook for 2 to 3 minutes',
            ],
            [
                'Cut the other vegetables. After the onion and the garlic are marrinated, add the different vegtables to the poth. Let them cook with the lid on for about 10 to 15 minutes or untill the vegetables are ready.',
            ],
            [
                'Once the vegetables are ready, add the tomato sauce and the tomato concentrate. Add the beans. Let this cook for another five minutes',
            ],
            [
                'Remove the lid from the pot. Add pepper and salt and other additional spcices, like italian spcies or special peppers',
            ],
        ],
    },
    {
        _id: 2,
        title: 'Eggs',
        type: 'Breakfast',
        category: 'vegan',
        image: 'http://via.placeholder.com/350x250',
        cookingTime: 10,
        ingredients: [
            [4, 'egg'],
            [1, 'tomato'],
            [1, 'pepper'],
            [1, 'salt'],
        ],
        cookingSteps: [
            [
                'cut the tomato. Heat olive oil in a pan, add the tomato and bake it till the outer peal of the tomato gets soft. If you like pepper, it is adviced to first bake the pepper a bit in the pan',
            ],
            [
                'Meanwhile, scrambel the eggs. Once the tomatoes are ready (see step 1), add the eggs',
            ],
        ],
    },
];

const Recipe = ({recipe}) => {
    const [isOpen, setIsOpen] = React.useState(false);

    return (
        <div className="col-md-3">
            <div className="card bwm-card">
                <div className="card-title">
                    <h2>{recipe.title}</h2>
                </div>
                <img className="card-img-top" src={recipe.image} alt={recipe.title} />
                <div className="card-subtitle">
                    <h3>
                        <b>Type: {recipe.type} </b>
                    </h3>
                    <h3>
                        <b>Category: {recipe.category}</b>
                    </h3>
                    <h3>
                        <b>Cooking time: {recipe.cookingTime} minutes</b>
                    </h3>
                </div>
                <div>
                    {isOpen ? (
                        <div className="card-body">
                            <div className="card-body-ingredient">
                                {recipe.ingredients.map((ingredient, i) => {
                                    return (
                                        <table>
                                            <tr>
                                                <th>Quantity</th>
                                                <th>Ingredient</th>
                                            </tr>
                                            <tr>
                                                <th>{ingredient[0]}</th>
                                                <th>{ingredient[1]}</th>
                                            </tr>
                                        </table>
                                    );
                                })}
                            </div>
                            <div className="card-body-cookingsteps">
                                {recipe.cookingSteps.map((cookingstep, i) => {
                                    return <p>{cookingstep}</p>;
                                })}
                            </div>
                            <div>
                                <button
                                    type="submit"
                                    value="Hide full recipe"
                                    onClick={() => setIsOpen(false)}>
                                    Hide full recipe
                                </button>
                            </div>
                        </div>
                    ) : (
                        <button
                            type="submit"
                            value="Show full recipe"
                            onClick={() => setIsOpen(true)}>
                            Show full recipe
                        </button>
                    )}
                </div>
            </div>
        </div>
    );
};

function DisplayRecipes() {
    return (
        <div className="card-list">
            <div className="container">
                <h1 className="page-title">Our vegan recipes...</h1>
                <div className="row">
                    {recipes.map((recipe) => (
                        <Recipe key={recipe._id} recipe={recipe} />
                    ))}
                </div>
            </div>
        </div>
    );
}

export default DisplayRecipes;

【讨论】:

    【解决方案2】:

    你可以考虑在这里使用refs

    ref 传递给您的onClickShow 并显示带有特定ref 的div。

    您也可以使用CSS,在这种情况下,使用ref 获取div,并将div 中的display 标记为none,反之亦然。

    【讨论】:

      猜你喜欢
      • 2018-09-21
      • 2021-09-27
      • 1970-01-01
      • 2021-05-07
      • 1970-01-01
      • 2014-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多