DEV Community

Cover image for The React Concept That Broke My Brain (And Why It Was Actually Simple)
BlackJosh007
BlackJosh007

Posted on

The React Concept That Broke My Brain (And Why It Was Actually Simple)

I almost skipped past this. It looked like a small refactor. It ended up being the first time React's "one source of truth" idea actually clicked for me instead of just being a phrase I nodded along to.

Here's the project: a grid of colored pads that toggle on/off when clicked. Simple UI, simple idea.

Where I started: derived state

My first instinct was to create state based on data that lived somewhere else in the component tree — what's usually called derived state. It technically worked. Buttons rendered, colors showed up. But something about it felt fragile, and I couldn't articulate why yet.

Where I ended up: one source of truth

The fix was to move the actual state up into App.jsx, and have everything else just receive data and functions as props. My folder looks like this:
1. App.jsx — holds the single source of truth:

export default function App() {
  const [pads, setPads] = React.useState(padsData)

  function toggle(idR) {
    setPads(prevPads => prevPads.map(item => {
      return item.id === idR ? { ...item, on: !item.on } : item
    }))
  }

  const buttonElements = pads.map(pad => (
    <Pad
      key={pad.id}
      color={pad.color}
      on={pad.on}
      toggleFunc={toggle}
      id={pad.id}
    />
  ))

  return (
    <div className="pad-container">
      {buttonElements}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

2. pads.js — the raw data the state is initialized from:

export default [
  { id: 1, color: "#F18D8B", on: true },
  { id: 2, color: "#F5C280", on: false },
  // ...
]
Enter fullscreen mode Exit fullscreen mode

3. Pad.jsx — a dumb component that just renders and reports back:

export default function Pad({ color, on, toggleFunc, id }) {
  return (
    <button
      style={{ backgroundColor: color }}
      className={on ? "on" : undefined}
      onClick={() => toggleFunc(id)}
    >
    </button>
  )
}
Enter fullscreen mode Exit fullscreen mode

The part that actually confused me

Not the state move itself — that part I could follow. What genuinely took time to reconcile was passing a function as a prop and tracking two different names for the same value:

  • In Pad.jsx: onClick={() => toggleFunc(id)} — here, id is the real value, the actual id of the button that got clicked.
  • In App.jsx: function toggle(idR) — here, idR is just a placeholder name, a parameter waiting to receive whatever value gets passed in.

I kept reading idR like it meant something special, like it was doing extra work. It isn't. It's just a name. The moment I stopped trying to find hidden meaning in idR and just traced the value — click happens → id gets passed → toggle receives it as idRidR gets compared against each item in state — the whole thing clicked into place.

The full loop, in plain language

  1. App.jsx holds pads state, seeded from padsData.
  2. It maps over pads and renders a Pad for each one, passing down color, on, id, and the toggle function itself.
  3. Pad.jsx attaches toggle to its button's onClick, wrapped in an arrow function so it can pass along which button was clicked.
  4. toggle receives that id (as idR), and calls setPads, mapping over the previous state and flipping on only for the item whose id matches.
  5. React re-renders with the updated state, and only the clicked button's color state changes.

Why this matters more than it looks like

The bug I would've eventually hit with derived state is the classic one: two sources of truth drifting out of sync. Lifting the state up removes that possibility entirely — there's exactly one place the "real" data lives, and everything else is just a reflection of it.

This is day-something of learning React in public, building toward real projects instead of just finishing tutorials. If you've hit this same wall with props/state, I'd like to hear how you reasoned through it.

Repo's on GitHub if you want to see the full thing — link in my profile.

Top comments (0)