Runnable lesson · press Try it on the examples to edit and run them here.
Props and state both hold data and both affect what appears on screen. They are easy to mix up at first. The difference is ownership.
The short version
| Props | State | |
|---|---|---|
| Who owns it? | The parent | The component itself |
| Can the component change it? | No, read-only | Yes, with the setter function |
| Where does it come from? | Passed in from outside | Created inside with useState |
| What happens when it changes? | The parent re-renders with new props, and the child re-renders | The component re-renders |
| A good comparison | Function arguments | Variables a function remembers between calls |
Seeing both in one example
function LikeButton({ label }) {
// label comes from outside, so it is a prop (read-only)
// count belongs to this component, so it is state
const [count, setCount] = React.useState(0);
return (
<div>
<p>Likes: {count}</p>
<button onClick={() => setCount(count + 1)}>{label}</button>
</div>
);
}
function App() {
return (
<div>
<LikeButton label="Like" />
</div>
);
}
labelis a prop.LikeButtoncannot change it. OnlyAppdecides it.countis state.LikeButtoncreated it and changes it.
State can become a prop
The same value can be state in one component and a prop in the next. A parent holds the state and hands the value to a child as a prop:
function Greeting({ name }) {
// name is a prop here
return <p>Hello, {name}</p>;
}
function App() {
// name is state here
const [name, setName] = React.useState("Ada");
return (
<div>
<input aria-label="Your name" value={name} onChange={(e) => setName(e.target.value)} />
<Greeting name={name} />
</div>
);
}
How to decide
Ask these questions about each piece of data, in order:
- Does it come from the parent? Then it is a prop.
- Does it stay the same over time? Then it is not state. Make it a constant or a prop.
- Can you calculate it from other props or state? Then it is not state either. Calculate it during render (see Derived State).
- Does it change over time because of the user or the network, and does the screen need to update when it does? Then it is state.
Minimal state is a good thing: every extra piece of state is something you can forget to update.
Common mistakes
- Copying a prop into state (
useState(props.value)). The state will not follow later changes to the prop. Use the prop directly, or lift the state up. - Trying to change a prop. React does not allow it, and mutating an object prop causes hard-to-find bugs. See Props Are Read-Only.
- Putting everything in state. Values you can compute do not belong there.
Key points
- Props are passed in and read-only; state is owned and changeable.
- A value can be state in a parent and a prop in a child.
- Keep state minimal and compute everything else.