Learn how to sync isolated components like an EpisodeList and PlayerBar by moving state to a shared parent, ensuring a single source of truth.

The fix is this concept called 'lifting state up,' which is really just about finding a mediator. You move that data to the closest common parent to create a single source of truth.
Lifting state up is the process of moving local state from individual child components to their closest common ancestor. This creates a "single source of truth," ensuring that sibling components—like a music player bar and a song list—stay synchronized. Instead of components trying to communicate sideways, which React does not support, they all receive the same data from the parent above them.
Since props are read-only, a child component cannot directly change the state living in a parent component. To handle updates, the parent must pass down a "remote control" in the form of a callback function. When an event occurs in the child, such as a user clicking a button, the child calls this function, which triggers the state setter in the parent and subsequently updates the entire data flow.
An uncontrolled component manages its own internal state independently, similar to a teenager managing their own schedule without the parent's knowledge. A controlled component is "driven" by its parent; it receives its data via props and notifies the parent of changes through callbacks. This makes the component more predictable, easier to test, and simpler to reuse because it no longer has a "hidden" internal agenda.
Lifting state is the preferred method for local coordination between a few related components. However, if you find yourself "prop drilling"—passing data through many layers of middleman components that don't actually use the data—it may be time for the Context API. Context acts as a "teleportation gate" for global data like user themes or authentication status, allowing deep child components to access information without manual prop passing at every level.
Copying a prop into a local state variable using useState(props.data) is dangerous because the state is only initialized once. If the parent’s data updates later, the child’s local state will not automatically reflect that change, leading to out-of-sync interfaces. The recommended approach is to use the prop directly; if you can calculate or derive a value from existing props, you should do so rather than storing it in a new state.
From Columbia University alumni built in San Francisco
"Instead of endless scrolling, I just hit play on BeFreed. It saves me so much time."
"I never knew where to start with nonfiction—BeFreed’s book lists turned into podcasts gave me a clear path."
"Perfect balance between learning and entertainment. Finished ‘Thinking, Fast and Slow’ on my commute this week."
"Crazy how much I learned while walking the dog. BeFreed = small habits → big gains."
"Reading used to feel like a chore. Now it’s just part of my lifestyle."
"Feels effortless compared to reading. I’ve finished 6 books this month already."
"BeFreed turned my guilty doomscrolling into something that feels productive and inspiring."
"BeFreed turned my commute into learning time. 20-min podcasts are perfect for finishing books I never had time for."
"BeFreed replaced my podcast queue. Imagine Spotify for books — that’s it. 🙌"
"It is great for me to learn something from the book without reading it."
"The themed book list podcasts help me connect ideas across authors—like a guided audio journey."
"Makes me feel smarter every time before going to work"
From Columbia University alumni built in San Francisco
