Weird behaviour of Loops in React

Hey dev fam! 👋
If you’ve ever written JavaScript (which, let’s be real, if you’re dabbling in React, you have), you know we have a whole Swiss Army knife of looping tools: for
, while
, do...while
, forEach
, for...of
, and on and on.
So naturally, when I first dipped my toes into React and JSX, I was like:
“Alrighty, time to
for
loop some components into existence!”
And JSX was like:
“LOL, no.”
Wait… why can’t I use for
or while
loops in JSX?
Great question! Let’s dive in.
First, remember that JSX isn’t exactly JavaScript — it's syntactic sugar that gets compiled down to React.createElement
calls under the hood. JSX expressions are evaluated within JavaScript expressions, not statements.
You can think of JSX as that fancy front door to a house that looks like JavaScript but actually has some strict HOA rules about what kind of code you're allowed to bring inside.
So here’s the kicker: for
and while
are statements, not expressions. And JSX only likes expressions. Think of JSX as that artsy minimalist friend who only lets you decorate their apartment using modular IKEA furniture and anything else just gives them anxiety.
Enter map()
— The superstar of JSX looping
map()
is an expression. It returns a value. And JSX loves that. You can drop it right into your render logic like the world’s chillest roommate.
Let’s say you have this array:
jsCopyEditconst fruits = ['🍎', '🍌', '🍇'];
And you want to render each fruit in a <li>
.
You can’t do this:
jsxCopyEdit<ul>
for (let i = 0; i < fruits.length; i++) {
<li>{fruits[i]}</li>
}
</ul>
That’ll throw JSX into an existential crisis. But you can do this:
jsxCopyEdit<ul>
{fruits.map((fruit, index) => (
<li key={index}>{fruit}</li>
))}
</ul>
Boom. Clean. Expressive. Functional. Your minimalist friend approves.
Real-world analogy time: JSX is a dinner party
Imagine JSX is a fancy dinner party. Every guest (aka child component) must bring a dish (aka return a value). map()
is that dependable friend who brings exactly what the host asked for — labeled, portioned, and plated.
Meanwhile, for
and while
show up with nothing but vague intentions and promises of helping in the kitchen. JSX ain’t got time for that. JSX wants that food on the table, now.
But wait, can I really not use for
or while
at all?
Actually… you can, just not inside JSX directly.
Here’s a cheeky workaround:
jsxCopyEditlet fruitItems = [];
for (let i = 0; i < fruits.length; i++) {
fruitItems.push(<li key={i}>{fruits[i]}</li>);
}
return <ul>{fruitItems}</ul>;
This works because the loop is run before JSX is evaluated. So technically, you’re not looping in JSX, you’re preparing JSX output before handing it off to your React component. It’s kind of like preheating your oven before cooking. Totally valid — just a bit less elegant and less "React-y".
Why not forEach()
then?
Aha! Good question, Watson.
Unlike map()
, the forEach()
method does not return anything. It’s like that one friend who listens to your problems and nods a lot but gives zero advice.
jsxCopyEdit<ul>
{fruits.forEach((fruit) => (
<li>{fruit}</li>
))}
</ul>
This will render nothing. Because forEach()
returns undefined
. JSX is like “Okay, cool, I guess I’ll just render nothing, then 😢.”
Bonus tip: Don't forget the key
prop
React gets real twitchy if you’re mapping over arrays without a key
prop. Like, screaming-in-the-console kind of twitchy.
Why? Because key
helps React efficiently re-render only what’s changed. It’s like giving your components name tags at that JSX dinner party. Without name tags, React gets confused and accidentally gives your banana component a grape’s memory. 🫠
So always do this:
jsxCopyEdit{items.map((item, index) => (
<ItemComponent key={item.id || index} data={item} />
))}
TL;DR (aka The Dev’s Espresso Shot ☕)
JSX only likes expressions, not statements.
map()
is a function that returns an array of elements → JSX is cool with that.for
,while
, andforEach()
don’t return renderable stuff → JSX gets confused.You can still use those old-school loops — just outside JSX.
Don’t forget the
key
prop when mapping!
Final Thoughts: Embrace the map()
lifestyle
Once you get used to map()
, it becomes second nature. Like switching from manual transmission to automatic. Sure, there’s a learning curve, but soon you’ll be breezing through UI lists like a boss.
And hey, if you ever feel weird about not using for
or while
anymore — just remember:
JavaScript gave you
for
, but React gave youmap()
— and honestly, React gave you the better gift. 🎁
Thanks for reading, folks!
If you enjoyed this post, let’s connect on Hashnode and talk more React quirks, memes, and dev-life epiphanies.
Subscribe to my newsletter
Read articles from Nurul Hasan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
