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

Asynchronous DynamoDB Queries with Java Using GSIs and the AWS SDK v2 Enhanced Async Client

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