1

I have an object containing several arrays like:

const Items = {
Deserts: [{name:cookies}, {name:chocolate}],
Fruits: [{name:apple}, {name:orange}]
...
}

I want to render it as:

<title>Deserts</title>
Cookies
Chocolate
<title>Fruits</title>
Apple
Orange

So first I render the type:


return <Grid>
    {Object.keys(Items).map(type => {
        return <Box key={type}>
            {type} // <== this would be the title, Fruits or whatever
            {this.createCard(Items[type])}
        </Box>
    })}
</Grid>

Then I want to add the content of each type:

createCard = (items) => {
  return <Box>
       {items.forEach(item => {
           return <div>{item.name}</div>
       })}
  </Box>
}

Content is not returned, it works fine if instead of a forEach loop I just add some predefined content.

Trax
  • 1,445
  • 5
  • 19
  • 39

2 Answers2

2

The forEach method only iterates over all items but does not return anything. Instead, what you want to use is a map. Also, make sure you wrap your return value when it extends more than one line:

createCard = (items) => {
  return (<Box>
       {items.map(item => {
           return <div>{item.name}</div>
       })}
  </Box>);
}

If you don't do that it works as if a semicolon was introduced after the first line. So, in reality, your current code is equivalent to:

createCard = (items) => {
  return <Box>;
  // The code below will never be executed!
       {items.forEach(item => {
           return <div>{item.name}</div>
       })}
  </Box>
}
mgarcia
  • 5,669
  • 3
  • 16
  • 35
  • Actually the second statement is not correct, it's perfectly fine to return Box without parentheses. ASCI will take place if you move to the next line after the return. Also don't forget to add a `key` – Asaf Aviv Nov 22 '19 at 22:27
0

When returning an element you need to wrap it in parentheses, ( ) and I generally use map instead of forEach.

const createCard = items => {
   return (
      <Box>
       {items.map(item => {
           return ( <div>{item.name}</div> )
       })}
     </Box>
   )
}

I believe you can also nix the curly braces if the function doesn't need any logic.

const createCard = items => (
    <Box>
        {items.map(item => {
            return ( <div>{item.name}</div> )
        })}
    </Box>
)

-- Edit --

Now that I'm reading back over your question a much cleaner way to approach this would be to declare the component function outside of your class like

class Grid extends react.Component {
   render(){
      return (
         <Box>
            <CreateCard props={ item }/>
         </Box
      )
   }
}

const CreateCard = props => (
    <Box>
        {props.items.map(item => {
            return ( <div>{item.name}</div> )
        })}
    </Box>
)
b.stevens.photo
  • 876
  • 2
  • 9
  • 18