简体   繁体   中英

React JS - data.map can't create list with the data

I got data.js file with some basic info for food like:

export default [
    {
        "name": "Crock Pot Roast",
        "information":[
            {
                "date":"24 July 2019",
                "type": "Main dish",
                "difficulty": "Easy",
                "time": "~50",
            }
        ],
        "ingredients": [
            {
                "quantity": "1",
                "name": " beef roast",
                "type": "Meat"
            }
        ],
        ...
        Some more data
        ...
    }
   ]

I want to create list on react that can get all elements from data.information which function will be correct to use?

I'm getting the data like this:

const getData = data.map(food => {
    return (
        <div key={food.name}>
            <span>{food.name}</span>
            <div>
                <div>
                    <img src={food.imageURL} alt={food.name} />
                    <div>
                        <ul>{getFoodInformation}</ul>
                    </div>
                </div>
            </div>

            <div>food ingredients</div>

            <div>food recipe</div>
        </div>
    );
});

but I can't use food.information.map to create list like:

<ul>{food.information.map((info) => <div key={info.date}>{info}</div>) }</ul>

Any ideas maybe to use another function not map?

You're right that this line is the problem:

<ul>{food.information.map((info) => <div key={info.date}>{info}</div>) }</ul>

But , .map() is not a problem. Your information data is an array, so you can .map() it with JSX.

Your problem is this:

<div key={info.date}>{info}</div>

info is an object, and React doesn't know how to print an object "beautifully". You want to use the string data (for example, {info.type} ).

If you need to dump the full object, use JSON.stringify like this:

<div key={info.date}>{JSON.stringify(info)}</div>

React does not render array/object into a list by default. you have to be explicit in your code.

your first attempt is 'close' to correct, however, you can notice, ingredients and information are both arrays of objects. it means that you have to generate a tag for each index.

I used JSON.stringify to generate a unique key since using an index for key is bad practice.

The code below shows you one of the correct approaches using react.

        const data = [
      {
        name: "Crock Pot Roast",
        imageURL: "https://via.placeholder.com/150",
        information: [
          {
            date: "24 July 2019",
            type: "Main dish",
            difficulty: "Easy",
            time: "~50"
          }
        ],
        ingredients: [
          {
            quantity: "1",
            name: " beef roast",
            type: "Meat"
          }
        ]
      }
    ];

    const CardRecipe = ({data}) => {
      const { name, imageURL, information, ingredients } = data;
      return (
        <div key={name}>
          <span>{name}</span>
          <div>
            <div>
              <img src={imageURL} alt={name} />
              <div>
                {information &&
                  information.map(info => {
                    const { date, type, difficulty, time } = info;
                    return (
                      <ul key={JSON.stringify(info)}>
                        <li> {date} </li>
                        <li> {type} </li>
                        <li> {difficulty} </li>
                        <li> {time} </li>
                      </ul>
                    );
                  })}
              </div>
              <div>
                {ingredients &&
                  ingredients.map(ingredient => {
                    const { quantity, name, type } = ingredient;
                    return (
                      <ul key={JSON.stringify(ingredient)}>
                        <li> {quantity} </li>
                        <li> {name} </li>
                        <li> {type} </li>
                      </ul>
                    );
                  })}
              </div>
            </div>
          </div>

          <div>food ingredients</div>

          <div>food recipe</div>
        </div>
      );
    };

    export default function App() {
      const first_reciepe = data[0];
      return (
        <div className="App">
          <CardRecipe data={first_reciepe} />
        </div>
      );
    }

Alternatively, you can print any lists by mapping once on the array, and then on each object/key to generate (x) amount of <"li"> tags.

Example:

const DoList = ({ data }) => {
  return data.map(list => {
    return (
      <ul key={list}>
        {Object.keys(list).map(key => {
          const value = list[key];
          return <li key={key}> {value} </li>;
        })}
      </ul>
    );
  });
};

Then you would use it as many time as you want like this:

<DoList data={ingredients} />
<DoList data={information} />
<DoList data={...} />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM