All posts
ReactOctober 19, 20267 min read

Lifting State Up in React Explained for Beginners

Lifting state up in React explained for beginners: learn how to share state between components with simple examples, clear steps and common mistakes to avoid.

F
Fepiq Team
Fepiq

Lifting state up in React means moving a piece of state from a child component to its closest shared parent, so that two or more components can use the same data. If you have ever asked "how do I share state between components in React?", this is the answer. In this guide you will learn what it means, why it is needed, and how to do it step by step with small examples.

You do not need to be an expert. If you know what a component, props and state are, you are ready. If not, a quick read of our guide on props vs state will help first.

The problem: two components need the same data

In React, data flows in one direction: from parent to child, using props. A child can read the props it receives, but it cannot hand data to its sibling directly. A sibling is another component that has the same parent.

Imagine a page with a text box and a preview below it. The preview must show whatever you type. If each component keeps its own state, they cannot see each other's data. Here is what that broken version looks like.

jsx
import { useState } from 'react';

function Input() {
  const [text, setText] = useState('');
  return <input value={text} onChange={(e) => setText(e.target.value)} />;
}

function Preview() {
  const [text, setText] = useState('');
  return <p>You typed: {text}</p>;
}

Both components have their own text state. Typing in Input changes only the Input copy. The Preview copy stays empty forever. They are two separate boxes that never talk to each other.

The solution: lift the state up

The fix has three steps. First, find the closest parent that contains both components. Second, move the state into that parent. Third, pass the value and a function to change it down to the children as props.

  1. Find the closest common parent of the components that need the data.
  2. Move the useState call into that parent.
  3. Pass the state value down as a prop.
  4. Pass the setter function down as a prop so children can ask for changes.

Step by step example: input and preview

Let us fix the broken example. We create a parent called App that owns the state.

jsx
import { useState } from 'react';

function App() {
  const [text, setText] = useState('');

  return (
    <div>
      <Input text={text} onTextChange={setText} />
      <Preview text={text} />
    </div>
  );
}

Line 4 creates the state in App, not in the children. In the Input line, we pass two props: the current value (text) and the setter function (onTextChange). In the Preview line, we pass only the value, because Preview just displays it.

jsx
function Input({ text, onTextChange }) {
  return (
    <input
      value={text}
      onChange={(e) => onTextChange(e.target.value)}
    />
  );
}

function Preview({ text }) {
  return <p>You typed: {text}</p>;
}

Input no longer has its own state. It shows the value it receives and, when you type, it calls onTextChange with the new text. That call runs setText inside App. React then re-renders App, and both children receive the new value. Now the preview updates as you type.

Why this works: a single source of truth

A source of truth is the one place where a piece of data really lives. After lifting state up, the text lives only in App. Everything else is a view of it. This avoids bugs where two copies of the same data disagree.

Data goes down through props. Changes go up through functions. Developers often say: data flows down, events flow up.

A second example: a shared counter total

Here is another common case. Two buttons each count clicks, and the parent shows the total.

jsx
function App() {
  const [likes, setLikes] = useState(0);
  const [loves, setLoves] = useState(0);

  return (
    <div>
      <CountButton label="Like" count={likes} onClick={() => setLikes(likes + 1)} />
      <CountButton label="Love" count={loves} onClick={() => setLoves(loves + 1)} />
      <p>Total: {likes + loves}</p>
    </div>
  );
}

function CountButton({ label, count, onClick }) {
  return <button onClick={onClick}>{label}: {count}</button>;
}

The parent holds both numbers, so it can add them up for the total. CountButton is now a simple reusable component with no state of its own. It receives a label, a count and a click handler. Components like this are easy to test and reuse.

When should you lift state up?

SituationWhat to do
Only one component uses the dataKeep the state inside that component
Two sibling components need the same dataLift state to their parent
A parent also needs to read the dataLift state to the parent
Many distant components need the dataLift higher, or later learn Context

A good rule: keep state as low as possible, and lift it only as far as needed. Lifting too high makes the parent messy.

Common beginner mistakes

  • Copying a prop into new state. This creates two sources of truth that can drift apart.
  • Forgetting to pass the setter function down, so the child cannot change anything.
  • Calling the function instead of passing it, such as onClick={handleClick()} instead of onClick={handleClick}.
  • Trying to change a prop inside the child. Props are read-only; ask the parent to change the state instead.
  • Lifting state too high when only one component needs it.

Quick recap

  • Siblings cannot share state directly.
  • Move the state to the closest common parent.
  • Pass the value down as a prop and the setter down as a prop.
  • The parent becomes the single source of truth.

Frequently asked questions

What does lifting state up mean in React?+

It means moving state from a child component into a shared parent component. The parent then passes the data down as props. This lets several components use and update the same data.

How do I share state between two components in React?+

Put the state in their closest common parent with useState. Pass the value to both children as props, and pass the setter function to any child that needs to change it.

Can a child component change the parent's state?+

Not directly. The parent passes down a function, usually the setter or a handler built from it. The child calls that function, and the parent updates its own state.

Is lifting state up the same as using Context?+

No. Lifting state up uses props and works well for nearby components. Context is a tool for sharing data with many deeply nested components without passing props through every level.

How far up should I lift state?+

Only to the closest parent that contains every component needing the data. Keeping state low makes your code simpler and easier to follow.

New to props and state? Read our beginner guide to understand the difference first.

Read props vs state

Want help building a React app for your business? Talk to the Fepiq team.

Contact Fepiq

Get new posts in your inbox

Occasional, no-fluff notes on shipping modern software — startups, automation, Laravel, Shopify and more. No spam, unsubscribe anytime.

Keep reading

Related posts

All posts

Let's build something

Ready to ship your next product with Fepiq?

Book a free discovery call. We'll listen, ask sharp questions, and send you a proposal within 3 business days.