Here’s Why You Shouldn’t Pass Props for Your useState Hook.
Let’s imagine a scenario where you’re building an ‘Edit Form’. You fetch some data in a parent component, pass it down to a child component…
Here’s Why You Shouldn’t Pass Props for Your useState Hook.
Photo by Ferenc Almasi on Unsplash
Let’s imagine a scenario where you’re building an ‘Edit Form’. You fetch some data in a parent component, pass it down to a child component as a prop, and use that prop to initialize your local useState so the user can type into the inputs.
The first time the page loads, it works perfectly. The inputs fill up with the right data, and you can edit them without any problem.
Then you test what happens when the data changes — like if the user switches to a different profile or the parent component refetches fresh data. You open your React DevTools and look at the child component. The props are absolutely changing.
But you look at the actual screen, and the form is still showing the old data. You click around, refresh, switch profiles again, and realize your form has completely out of sync with the rest of your app.
This is the Prop-to-State Problem. It is incredibly frustrating because the code looks fine, but the UI tells a different story.
Discrepancy Between the Parent and the Child Component
Here is the exact pattern that gets everyone stuck. You take a prop — like a user’s initial name — and dump it straight into a local state variable:
import React, { useState } from 'react';
// The parent passes down the fresh data it fetched
function EditProfile({ initialName }) {
// You mirror it into local state so you can control the input
const [name, setName] = useState(initialName);
return (
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
);
}
The logic makes sense in your head: you need to edit the name, so the name has to live in a state. The state needs a starting value, so you give it initialName.
But here is the catch with useState that trips everyone up: The initial value you pass to useState only runs exactly once—when the component is rendered for the very first time.
When the parent component re-renders and hands down a brand-new initialName prop, React looks at the child component, sees it already exists on the screen, completely ignores the new initial value and the child component renders the old stale data.
The local name state just holds onto whatever it had before. By copying the prop into state, you accidentally duplicated the data.
Using a useEffect (It Doesn’t Fix The Problem)
When you first hit this bug, the immediate panic move is to force the state to update using a useEffect:
// AVOID THIS
useEffect(() => {
setName(initialName);
}, [initialName]);
We have all tried this, but it introduces a whole new set of problems for us. First, it causes a double-render glitch. The component renders once with the old data, notices the prop changed, runs the effect, updates the state, and then renders a second time to show the new data.
Even worse, if your user is in the middle of typing something into the form, and the parent component happens to re-render for a completely unrelated reason (like a global state update or a timer), this effect will trigger and completely wipe out everything the user typed mid-keystroke.
The Fix
You don’t need a useEffect hook. You can handle this cleanly depending on what your component actually needs to do.
1. The ‘key’Prop Reset (The Best Way for Forms)
If the child component is a form and genuinely needs local state so the user can type, the fix doesn’t belong in the child component at all. It belongs in the parent.
You can use React’s built-in key prop to tell the framework exactly when to remove the old form and start fresh.
// Inside the Parent Component
function ProfileManager() {
const { user, isLoading } = useUserData();
if (isLoading) return <p>Loading...</p>;
// Changing the key forces React to completely rebuild the component
return <EditProfile key={user.id} initialName={user.name} />;
}
The key prop isn't just for rendering lists of items. In React, when a component's key changes, React completely destroys the old component instance and mounts a brand-new one, and runs useState completely fresh. The form resets instantly with the correct data, with no state bugs.
2. Let’s Not Use the State (If You Don’t Need to Edit)
If the child component doesn’t actually need to change the data — if it’s just displaying it or doing some math with it — delete the useState block entirely. Just read the prop directly in your HTML.
// No state needed if you aren't changing the value locally
function ProfileDisplay({ name }) {
return <h1>Welcome back, {name}!</h1>;
}
If you don’t copy the prop into state, it can never fall out of sync. The child will always show exactly what the parent sends down.
The Lesson Learned
Copying props into state comes from a completely natural instinct: you just want to make the data interactive. But the moment you duplicate a single piece of information into two different states, there are gonna be sync issues.
Avoid the temptation to patch it with an useEffect to solve the problem ASAP. Use the
keyprop strategy to let the component reset naturally or just pass the prop directly to the child component (whatever goes with your flow).
메타데이터
- post_id
- 7f6aa9e9592b
- slug
- heres-why-you-shouldn-t-pass-props-for-your-usestate-hook-7f6aa9e9592b
- url
- https://blog.stackademic.com/heres-why-you-shouldn-t-pass-props-for-your-usestate-hook-7f6aa9e9592b
- canonical_url
- https://blog.stackademic.com/heres-why-you-shouldn-t-pass-props-for-your-usestate-hook-7f6aa9e9592b
- author_url
- https://medium.com/@kumarshreyash139
- status
- ok
- fetched_at
- 2026-07-18 01:24:29