1

I'm trying to do something very simple but its not playing well with my code. I can see it render but only 3 times and not 9

const renderTempBoxes = () => {
  for (var i = 0; i < 10; i++) {
    console.log('i = ', i);
    return <div className={styles.box} key={i} />;
  }
};

const Component = () => {
  return (
   {renderTempBoxes()}
  )
}

This doesn't even work, which is overkill to use an array when I just want 9 boxes to render. UPDATE:

const Component = () => {
  return (
   <div>
     {
      [...Array(10)].map((x, i) => {
        console.log('i = ', i);
        return <div className={styles.box} key={i} />;
      })
     }
    </div>
  )
}

2 Answers 2

2

The first issue is that you simply cannot return individual elements from within the for loop like that. This is not specific to React, this is simply a JavaScript issue. Instead you can try something like this using Array.from to map an array of elements:

const renderTempBoxes = () => Array.from({ length: 10 }).map((v, i) => 
    <div className={styles.box} key={i}>{i}</div>
);

Or simply the for loop with Array.prototype.push to generate an array of elements and return it:

const renderTempBoxes = () => {
  let els = [];

  for (let i = 0; i < 10; i++) {
    els.push(<div className={styles.box} key={i}>{i}</div>);
  }

  return els;
};

Rendering the elements:

const Component = () => {
  return (
   <div>
     {renderTempBoxes()}
   </div>
  )
}

Or with React.Fragment to forgo the wrapping extra node:

const Component = () => {
  return (
   <React.Fragment>
     {renderTempBoxes()}
   </React.Fragment>
  )
}

The second issue with your example is that <div /> isn't going to really render anything, it's not a void/self-closing element such as <meta />. Instead you would need to do return the div element as <div className={styles.box} key={i}>{whatever}</div>.

Regarding the syntax [...Array(10)], there must be an Webpack in terms of how it handles/transpiles Array(10), [...Array(10)], [...new Array(10)], or even `[...new Array(10).keys()]. Either of the approaches described in the answer should solve your issue.

I've created a StackBlitz to demonstrate the functionality.

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

7 Comments

Ok this makes sense but in my second example I use an array. I updated it to be wrapped in a div and it still doesn't work. <div> { [...Array(10)].map((x, i) => { console.log('i = ', i); return <div className={styles.box} key={i} />; }) } </div>
I'm going to update my post to show it more clearly. Sorry for just pasting code into the comment.
Check out the StackBlitz in demonstrates both approaches in action as well as use of React.Fragment. Thanks!
Ok all those make sense but isn't that similar I'm doing in my second example.
Your second approach is effectively the same. I think the issue with your example is attempting to return the element as <div className={styles.box} key={i} />. Try <div className={styles.box} key={i}>{i}</div> or similar as a self closing tag. When I tried your exact methods, nothing rendered in StackBlitz. I updated it show that exact issue happening. If you were rendering a React component in that self closing fashion, it would work, but not '<div />'.
|
0

When trying to render multiple times the same components use an array an map over it.

export default class MyComp extends Component {

 constructor(props) {
  super(props)
  this.state = {
   array: [{key: 1, props: {...}}, {key: 2, props: {...}, ...]
  }
 }

 render () {
   return (
     <div>
      {this.state.array.map((element) => {
      return <div key={element.key} {...element.props}> 
     })}
     </div>
   )
 }
}

Remember to always set a unique key to every component you render

11 Comments

Right but I'm doing something quick and dirty so why create an array when I just want to create 9 boxes. Array is a little overkill in this case.
If you want to render multiple components like this, at some point you will need to pass an array to the render function. Another option would be to create an array in which every element is a component. But still an array. And what if later you want more or fewer boxes? This way you just need to update the state
So you are saying you can only use arrays when trying to render a set amount of div's ? You can not use a for loop ? I'm only trying to do something quick not for scalability right now. I'm surprised that only arrays will allow you to render multiple divs
In my second example I use an array just to test and that gave me an error. Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.
Yes, how would you use one single function and return something 9 times? You can see that in the other answer he also returns an array. What you could do is use a for loop to add 9 Div inside another main Div and return the Main div
|

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.