AV
HomeAboutProjectBlog

© 2026 Ave syah Shina. All rights reserved.

  1. Home
  2. Blog
  3. 02 — Props, State, and Refs — The Three Ways a Component Holds Data

02 — Props, State, and Refs — The Three Ways a Component Holds Data

August 13, 20267 min read
Download as Markdown

Props, state, and refs blurred into "just variables the component knows about" until I separated them by job. The split that made them click: props are inputs handed down by the parent, state is the component's own memory that drives re-renders, and refs are an escape hatch for values that must persist across renders without triggering them. [1][2] Each one exists for a different reason, and mixing them up is the source of most beginner confusion.

Props: the inputs a parent hands down

Props (short for properties) are the channel a parent uses to configure a child [1]. They're the function-argument equivalent — when I write <Card title="Hello" />, title is a prop the Card component receives. Three things define props:

  • They flow top-down. A parent passes them; the child reads them. Data moves parent → child, never the reverse, unless the parent explicitly passes a callback prop the child invokes.
  • They're read-only. A component must never mutate its own props [1]. If a value needs to change, that value is state, not props.
  • They trigger renders. New prop values from the parent cause the child to re-render.

That second rule is the one I had to take seriously. "Treat props as immutable" is what keeps the component a pure function of its inputs — same props in, same JSX out. The moment I'm tempted to write to a prop, I've actually discovered I need state, or I need to lift the state up to the parent.

State: the component's own memory

State is the component's private memory — values it owns and can change, where each change schedules a re-render [2]. Where props come from outside, state lives inside the component. In a functional component, state is created with the useState hook (covered in its own notes); for now the conceptual point matters more than the syntax:

  • State changes are the engine of re-rendering. Mutating a state variable directly does nothing visible — I have to call the setter React gives me, which queues a new render.
  • State is per-instance. Two <Counter /> components on the page each keep their own count.
  • Updates may be asynchronous and batched, so I read the latest value through the setter's callback form when the next value depends on the previous.
function Counter() {
// count is state: private to this instance, changing it re-renders
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}

The contrast with props is the whole story: props are configuration from the parent, state is memory the component controls. A common rookie move is to duplicate a prop into state ("I'll copy initialName into a state variable and edit that"). That's almost always wrong — it creates two sources of truth that drift apart. If the parent's value should drive the child, read the prop directly; if the child owns the editable value, the prop is just a seed.

Refs: the escape hatch that doesn't re-render

Refs are the third channel, and the one I resisted longest. A ref holds a mutable value that persists across renders but does not trigger a re-render when it changes [3][4]. There are two jobs refs are actually for:

  • Reaching into the DOM. To focus an input, measure an element, or integrate with a non-React library, I need the actual DOM node. A ref attached via <input ref={myRef} /> gives me that node imperatively [3].
  • Storing a value that shouldn't cause renders. A debounce timer ID, a "has this effect run" flag, a cached value — things I need to remember across renders but where a re-render would be pointless or harmful.
function FocusInput() {
const inputRef = useRef(null);
const handleClick = () => inputRef.current.focus(); // imperative DOM access
return (
<>
<input ref={inputRef} />
<button onClick={handleClick}>Focus</button>
</>
);
}

The rule I follow for refs: if the value should change the UI when it changes, it's state, not a ref. Refs are deliberately outside React's render loop — that's their power and their danger. Every ref write is a place React isn't watching, so it's a place bugs hide. I reach for a ref only when state genuinely can't do the job (DOM access, or a value that must not cause renders).

Parent props read-only · top-down Component state private · re-renders refs escape hatch · no render setter → re-render DOM node / value props in from parent · state owned · refs out of band

How I use this

Before I add any data to a component, I run it through the three-question check:

  • Does this value come from the parent? → props. Don't copy it into state.
  • Does this value belong to this component, and should the UI change when it does? → state. Use the setter, never mutate directly.
  • Does this value need to persist across renders but _not_ re-render when it changes (a DOM node, a timer, a cache)? → ref.

That check resolves almost every "where does this data go" question. The remaining one — state shared between siblings — is "lift it up to the common parent," which is also why I reach for context or a state library once the lifting gets deep.

References

[1] React team, "Passing props to a component," react.dev, 2024. [Online]. Available: https://react.dev/learn/passing-props-to-a-component

[2] React team, "State: a component's memory," react.dev, 2024. [Online]. Available: https://react.dev/learn/state-a-components-memory

[3] React team, "Referencing values with refs," react.dev, 2024. [Online]. Available: https://react.dev/learn/referencing-values-with-refs

[4] React team, "Manipulating the DOM with refs," react.dev, 2024. [Online]. Available: https://react.dev/learn/manipulating-the-dom-with-refs

[5] R. Wieruch, "What is the difference between state and props in React?," Stack Overflow, 2023. [Online]. Available: https://stackoverflow.com/questions/27991366/what-is-the-difference-between-state-and-props-in-react

[6] D. Pavlutin, "The complete guide to useRef() and refs in React," dmitripavlutin.com, 2023. [Online]. Available: https://dmitripavlutin.com/react-useref-guide/

Knowledge check · Question 1 of 5

Which data channel is read-only and flows only from parent to child?

Comments

Leave a Comment

You must be signed in to comment

0 Comments

No comments yet. Be the first to comment!