What are props (and how are they different from state)?
In one sentence:Props are the labeled, read-only inputs a parent component passes down to a child component, flowing one way and never changed by the child that receives them.
What it actually is
Props (short for properties) are the labeled inputs a parent hands to a child component when it renders it. If a component is a function, props are the arguments you call it with: <Avatar person={user} size={100} /> passes a person object and a size number into Avatar, which reads them back out as function Avatar({ person, size }) { ... }.
The rule that trips people up is direction: data only travels one way, from parent down to child. React’s own docs call this one-way data flow, data flows down from the top-level component to the ones at the bottom of the tree, and a child can never hand a value back up through a prop. Props are also immutable: a child can’t rewrite what it receives. To change what a child displays, the parent has to send a new set of props, a new object, not an edited version of the old one.
That’s props vs state in one line. Props arrive from outside and you can’t touch them. State is data a component manages for itself, and it can change that whenever it wants.
Why your AI just did this
Most components your agent writes take some data as props, since that’s what makes components reusable: <Button label="Save" /> and <Button label="Cancel" /> render from the same component with different props. That pattern is the same whether you’re building in Lovable, Cursor, Bolt, or Claude Code, because it comes from React itself, not any one tool.
Your agent brings up “passing props down” when a value lives higher in the tree than the piece that needs to display it. Say your app fetches a user’s name from your backend (see frontend vs backend), and a Profile header three components down needs to show it. Since props only flow one way, the agent has to add that name as a prop on every component in between, even ones that never use it, just to relay it along. React’s own docs name this pattern prop drilling and call it verbose and inconvenient once a value crosses several layers, which is why a request as small as “show the username in the header” can turn into edits across four files. For a value many components need at different depths, Context offers a shortcut around that chain, and your agent may reach for it once the chain gets long enough to hurt.
When you’ll run into it
You’ll see props most often as JSX attributes: <Card title="Getting started" />. If your project uses TypeScript, which most agent-scaffolded apps do, you’ll also meet them as a build error when a required prop goes missing:
error TS2741: Property 'title' is missing in type '{}' but required in type 'CardProps'.
That means some Card is being rendered without a value its own type definition marks as required. Fix the call site that forgot title, or loosen a type definition that shouldn’t require it.
You’ll also spot it in the browser when something renders blank or as undefined: the parent never passed that data, or passed it under a different name than the child expects (userName versus name is a classic typo). And you’ll hear “prop drilling” itself as a complaint, when your agent has added one prop to four or five components purely to relay it down the tree.
What to check
- When something renders as
undefined, trace it backward: find the JSX tag that renders the component and confirm the parent actually passed that named prop - For a required-prop TypeScript error, check the component’s type definition first; the fix is either passing the missing value at every call site or making the prop genuinely optional
- If your agent threads one prop through four or five components that don’t use it, ask whether Context or fetching the data closer to where it’s needed would be simpler
- Don’t ask your agent to “just change the prop” from inside the component that receives it. Props are read-only; ask it to move that value into state instead
- Watch for prop name mismatches between parent and child (
onClickvshandleClick,valuevsdata); nothing throws an error, the value just quietly becomesundefined
Say it like a dev
Instead of: “the profile picture isn’t showing up” Say: “The Avatar component isn’t getting the person prop. Can you check what the parent is actually passing it?”
Instead of: “why do I have to change five files for one value” Say: “This looks like prop drilling. Can we use Context instead of passing this value through every component in between?”
Instead of: “make it so clicking updates the name here” Say: “The name needs to change when the button is clicked, so it should live in state, not arrive as a fixed prop.”
People actually ask
“What's the difference between props and state?”
Props are data a parent component hands to a child; the child can read them but never change them. State is data a component manages for itself, usually with useState, and only that component can update it directly. When your agent explains a bug by pointing at 'the wrong prop' versus 'the wrong state', it's telling you exactly where the data actually lives.
“Why does my agent keep saying it needs to pass props down?”
Because React data flows one direction: from a parent component to its children, never back up. If a value lives near the top of your app but a component several layers down needs it, your agent has to add that value as a prop on every component in between, even the ones that just relay it. That chain is called prop drilling, and it's one reason a small-sounding change touches several files.
“Can I change a prop from inside the component that receives it?”
No. React's own docs describe props as immutable, meaning a component can read the props it's given but can't rewrite them. If the displayed value needs to change, say after a click, that value belongs in state, either in the component itself or in a parent that later passes an updated prop back down.
Related terms
Checked against
Just met this in a real session? Glim reads it in plain words.
Paste what your agent just did, a git diff, your terminal, or its summary, and Glim tells you what changed and what to check before you ship. Nothing stored.
Explain my session →