Is there a way to map () an array of objects in React?

1

I'm doing a project where I need several recipe cards that will contain: title and ingredients. These cards should be expandable (the user will see the title and when clicking, the ingredients will be shown) and to facilitate, I am using the Ui Material.

As I do not know the amount (the application will be dynamic), I would like to use map() and I noticed that I will need two map() : One for the cards and another for the list of ingredients that will be rendered inside the card

Below are: the input object sample I used to test, how I thought about doing this object manipulation, and the error message displayed.

Input example:

 const teste2 =[{
   title:"Brigadeiro",
   ingredients:["margarina","achocolatado","leite condensado"]
 },{
   title: "Pão assado",
   ingredients:["pão","margarina"]
 }]

As I thought of doing:

 const Recipes = (props) =>{
   let recipesList = props.objects.map((object, index)=>{

     let ingrList = object.ingredients.map((ingred,index)=>(
     <CardText expandable={true}>
       {ingred}
     </CardText>
   ))

     return(
       <Card>
         <CardHeader
           title={object.title}
           actAsExpander={true}
           showExpandableButton={true}
         />
         <CardText>
           {ingrList}
         </CardText>
       </Card>
   )})
 }

Error:

 Recipes(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
 Evaluating index.js

Would anyone have a clue what to do? Is there a map() method for objects?

Note:

I tried to separate the objects, creating one for the ingredient lists and rendering it inside the recipe cards, but the expandable={true} property of the <CardText> component stops working (ingredients always appear expanded). Note that in this test, I did not use objects.

    
asked by anonymous 16.02.2018 / 23:39

2 answers

0

The error occurs because there is nothing being returned from the render() method. This is clear from the code and error message.

Here's my suggestion to solve the problem: split the user interface into smaller parts. The problem becomes easier to solve. Each component or function must have only one responsibility. Come on:

(1) Create a Recipes component for all recipes.

(2) Create a component Recipe for only one recipe.

(3) Create a Ingredient component for each ingredient.

1. Recipes.js

The Recipes component is only imported into several Recipe components.

(e.g.
  props.recipes === 
    [
      {
        id: 123,
        title: "Brigadeiro",
        ingredients: ["margarina", "achocolatado", "leite condensado"]
      },
      {
        id: 124,
        title: "Pão assado",
        ingredients: ["pão", "margarina"]
      }
    ]
)
const Recipes = (props) => {
  const recipeComponents = props.recipes.map(recipe => (
    <Recipe key={recipe.id} recipe={recipe} />
  ));

  return (
    <div>
      <h1>Receitas</h1>
      {recipeComponents}
    </div>
  );
};

2. Recipe.js

The Recipe component shows an individual recipe (and several ingredients).

(e.g. props.recipe === 
  {
    title:"Brigadeiro",
    ingredients: ["margarina", "achocolatado", "leite condensado"]
  }
)
const Recipe = (props) => {
  const ingredientComponents = props.recipe.ingredients.map(ingredient => (
    <Ingredient key={ingredient} ingredient={ingredient} />
  ));

  return (
    <Card>
      <CardHeader
        title={props.recipe.title}
        actAsExpander={true}
        showExpandableButton={true}
      />
      {ingredientComponents}
   </Card>
  );
};

3. Ingredient.js

The Ingredient component has the role of rendering an individual ingredient.

(e.g. props.ingredient === "margarina")
const Ingredient = (props) => {
  return (
    <CardText expandable={true}>
      {props.ingredient}
    </CardText>
  );
};

Note: All necessary imports have been omitted to focus on the issue in question.

    
09.03.2018 / 19:44
0

I have done with state instead of props, if it works this way, just change it later:

import React, { Component } from 'react';

class Recipes extends Component {
    constructor(props) {
        super(props);
        this.state = {
            teste2: [
                {
                    title:"Brigadeiro",
                    ingredients: ["margarina","achocolatado","leite condensado"]
                },{
                    title: "Pão assado",
                    ingredients: ["pão","margarina"]
                }
            ]
        }
    }
    render() {
        return (
            <Card>
                { this.state.teste2.map((valor, x) => {    
                    return (
                        <CardHeader
                            title={ valor.title }
                            actAsExpander={ true }
                            showExpandableButton={ true }
                            key={ x }
                        />
                        <CardText>
                            { valor.ingredients.map((ingred) => {
                                return { ingred }
                            }) }
                            { ingrList }
                        </CardText>                        
                    )                
                }) }
            </Card>
        );
    }
}
    
18.04.2018 / 15:38