Weird behaviour of Loops in React

Nurul HasanNurul Hasan
4 min read

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, and forEach() 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 you map() — 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.

0
Subscribe to my newsletter

Read articles from Nurul Hasan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Nurul Hasan
Nurul Hasan