React Parent-Child Communication

React Parent-Child Communication

React Parent-Child Communication: How to Pass Data and Callbacks Between Components

React is all about component-based architecture, which means breaking your UI into small, reusable pieces. But when components need to talk to each other, especially parent ↔ child, it can get tricky. In this article, we’ll walk through a practical example that shows:

  • How a parent component passes data to a child
  • How a child component sends data back to the parent
  • Using state and callbacks to keep everything in sync

We’ll use a simple counter app to illustrate the concepts.

The Scenario

Imagine we have:

  1. A Parent component that maintains a counter (parentCounter) and a message from its child (messageFromChild).
  2. A Child component that also has its own counter (childCounter) and can send messages back to the parent.

We want:

  • Parent → Child communication: Parent passes its counter value as a prop to the child.
  • Child → Parent communication: Child sends messages back via a callback prop.

Parent Component

import { useState } from "react";
import Child from "./Child";

export default function App() {
  const [messageFromChild, setMessageFromChild] = useState("");
  const [parentCounter, setParentCounter] = useState(0);

  // Callback for Child → Parent
  const handleChildMessage = (msg) => {
    setMessageFromChild(msg);
  };

  return (
    <div style={{ padding: 20 }}>
      <h1>Parent Component</h1>

      <p>Message from Child: {messageFromChild}</p>
      <p>Parent Counter: {parentCounter}</p>

      <button onClick={() => setParentCounter(parentCounter + 1)}>
        Increase Parent Counter
      </button>

      <Child
        parentValue={parentCounter}
        onSendMessage={handleChildMessage}
      />
    </div>
  );
}

Breaking it down

  • State Management in Parent:
    const [messageFromChild, setMessageFromChild] = useState("");
    const [parentCounter, setParentCounter] = useState(0);

    parentCounter keeps track of the parent's counter value. messageFromChild stores messages received from the child component.

  • Defining a callback function:
    const handleChildMessage = (msg) => {
      setMessageFromChild(msg);
    };

    This allows the child component to “send data up” to the parent.

  • Passing props to the child:
    <Child
      parentValue={parentCounter}
      onSendMessage={handleChildMessage}
    />

    Enables both Parent → Child and Child → Parent communication.

Child Component

import { useState, useEffect } from "react";

export default function Child({ parentValue, onSendMessage }) {
  const [childCounter, setChildCounter] = useState(0);

  useEffect(() => {
    onSendMessage(`Child counter is now ${childCounter}`);
  }, [childCounter]);

  return (
    <div style={{ marginTop: 20, padding: 15, border: "1px solid gray" }}>
      <h2>Child Component</h2>

      <p>Received Parent Counter: {parentValue}</p>
      <p>Child Counter: {childCounter}</p>

      <button onClick={() => setChildCounter(childCounter + 1)}>
        Increase Child Counter
      </button>

      <button onClick={() => onSendMessage(`Child clicked button!`)}>
        Send Message to Parent
      </button>
    </div>
  );
}

Key Points

  • Props from Parent: The child receives parentValue and onSendMessage.
  • Child's own state: childCounter tracks the child’s counter independently.
  • Sending data automatically: The useEffect hook notifies the parent whenever childCounter changes.
  • Sending data manually: Clicking the “Send Message to Parent” button calls the callback immediately.

Parent → Child Communication

Whenever parentCounter changes, the child automatically receives the updated value through parentValue. React re-renders the child component.

Child → Parent Communication

The child cannot directly change the parent’s state. Instead, it calls the callback function provided by the parent (onSendMessage), which updates the parent state (messageFromChild).

The Big Picture: Two-Way Data Flow

Direction Mechanism Example
Parent → Child Props parentValue={parentCounter}
Child → Parent Callback function passed as prop onSendMessage={handleChildMessage}

Demo in Action

  • Clicking “Increase Parent Counter” updates parentCounter and the child sees the updated value.
  • Clicking “Increase Child Counter” updates childCounter and automatically sends a message to the parent.
  • Clicking “Send Message to Parent” sends a custom message immediately.

Why This Pattern Matters

Parent-child communication in React is everywhere, from forms to dashboards. Understanding props + callbacks is foundational before exploring advanced state management like Context API or Redux.

Conclusion

Parent-child communication in React relies on props for passing data down and callbacks for sending data up. With a combination of useState and useEffect, you can create dynamic, interactive, and synchronized UIs.

Comments

Popular posts from this blog

Building and Deploying a Fargate Container that runs Python and performs CloudWatch Logging

Automate Your API Gateway Setup with Boto3: Rendering HTML from Lambda

Setting up an AWS Cognito User Pool and building a React login component