DEV Community

Cover image for Step-by-Step Guide: Parent/Child Components and Lifting State
kelseyroche
kelseyroche

Posted on

Step-by-Step Guide: Parent/Child Components and Lifting State

In React, components often need to share information. To do this, we use parent/child relationships and sometimes need to “lift state” so components can communicate effectively. Here’s a simple guide to get you started.

Summary

  1. Parent-to-Child Communication: Pass data using props.
  2. Child-to-Parent Communication: Use functions passed as props to update the parent’s state.
  3. Lifting State: Move state to the nearest common parent to share it between sibling components.

1. Parent and Child Components

Think of a parent component and child components quite literally as a parent and their children. The parent manages the house and passes chores down to the children.

Let’s create two components: Parent and Child. The parent will pass data to the child using props.

Parent Component:

import React from 'react';
import Child from './Child';

function Parent() {
  const message = "Hello from Parent!";

  return (
    <div>
      <h1>Parent Component</h1>
      <Child message={message} />
    </div>
  );
};

export default Parent;

Enter fullscreen mode Exit fullscreen mode

What do you think is the prop we will pass down to the Child?

Child Component:

import React from 'react';

function Child({ message }) {
  return (
    <div>
      <h2>Child Component</h2>
      <p>{message}</p>
    </div>
  );
};

export default Child;
Enter fullscreen mode Exit fullscreen mode

When you render Parent, the child will display:

Hello from Parent!

2. Lifting State Up

Sometimes, a child component needs to send data back to its parent. This is where we “lift state.”

Here’s an example where the child sends a message to the parent:

Parent Component:

import React, { useState } from 'react';
import Child from './Child';

function Parent() {
  const [childMessage, setChildMessage] = useState("");

  const handleMessage = (message) => {
    setChildMessage(message);
  };

  return (
    <div>
      <h1>Parent Component</h1>
      <p>Message from Child: {childMessage}</p>
      <Child onSendMessage={handleMessage} />
    </div>
  );
};

export default Parent;
Enter fullscreen mode Exit fullscreen mode

Child Component:
What props do you think we will be passing down to the Child function?


import React from 'react';

function Child({ onSendMessage }) {
  const sendMessageToParent = () => {
    onSendMessage("Hello from Child!");
  };

  return (
    <div>
      <h2>Child Component</h2>
      <button onClick={sendMessageToParent}>Send Message to Parent</button>
    </div>
  );
};

export default Child;
Enter fullscreen mode Exit fullscreen mode

Now, when you click the button in the child component, the parent updates its state and displays:

Message from Child: Hello from Child!

3. Why Lift State?

  • If two child components need to share data, the parent can manage the state and pass it to both children.
  • It avoids redundant state logic across components.

Example: Sibling Communication

import React, { useState } from 'react';
import ChildOne from './ChildOne';
import ChildTwo from './ChildTwo';

function Parent ()  {
  const [sharedState, setSharedState] = useState("");

  return (
    <div>
      <h1>Parent Component</h1>
      <ChildOne setSharedState={setSharedState} />
      <ChildTwo sharedState={sharedState} />
    </div>
  );
};

export default Parent;
Enter fullscreen mode Exit fullscreen mode

ChildOne Component:

import React from 'react';

function ChildOne ({ setSharedState }) {
  return (
    <div>
      <h2>Child One</h2>
      <button onClick={() => setSharedState("Message from Child One")}>
        Send to Child Two
      </button>
    </div>
  );
};

export default ChildOne;
Enter fullscreen mode Exit fullscreen mode

ChildTwo Component:

import React from 'react';

function ChildTwo ({ sharedState }) {
  return (
    <div>
      <h2>Child Two</h2>
      <p>{sharedState}</p>
    </div>
  );
};

export default ChildTwo;
Enter fullscreen mode Exit fullscreen mode

When ChildOne sends a message, ChildTwo automatically receives it via the parent.

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more