React render from a loop

React render from a loop



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



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:


for


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:


for


Array.prototype.push


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:


React.Fragment


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>.


<div />


<meta />


<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.


[...Array(10)]


Array(10)


[...Array(10)]


[...new Array(10)]



I've created a StackBlitz to demonstrate the functionality.





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>
– me-me
Aug 30 at 18:40





I'm going to update my post to show it more clearly. Sorry for just pasting code into the comment.
– me-me
Aug 30 at 18:41





Check out the StackBlitz in demonstrates both approaches in action as well as use of React.Fragment. Thanks!
– Alexander Staroselsky
Aug 30 at 18:51


React.Fragment





Ok all those make sense but isn't that similar I'm doing in my second example.
– me-me
Aug 30 at 19:13





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 />'.
– Alexander Staroselsky
Aug 30 at 19:16



<div className=styles.box key=i />


<div className=styles.box key=i>i</div>



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





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.
– me-me
Aug 30 at 18:20





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
– Lucas Fabre
Aug 30 at 18:25






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
– me-me
Aug 30 at 18:27





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.
– me-me
Aug 30 at 18:28





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
– Lucas Fabre
Aug 30 at 18:30



Required, but never shown



Required, but never shown






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)