December 16, 2023

Pass Data From Child to Parent Component in React

In this tutorial we'll see how does the communication from child to parent component happen in React.

Passing data from the child to parent component in React is done using the following steps-

  • Create a function in the parent component that takes in a parameter. This callback function will get the data from the child component.
  • Pass this function as a prop from the parent to the child component.
  • The child component calls the parent callback function using props.

Let’s try to understand this child to parent communication in React using examples. In the first example we’ll just have a form with single input element in the Child component and the data entered in this form is then sent to the parent component.

Second example will be a bit complex where we’ll have a form to add products and then that data is added to the already existing list of products.

1. In the example there are two components Parent.js and Child.js

The Child component has a form which sends its data up to the Parent component when the form is submitted. Note that react-bootstrap is used for styling here which can be installed using npm install react-bootstrap bootstrap

Parent.js
import Child from "./Child"
import React, {useState} from "react";

const Parent = () =>{
  const [initText, setText] = useState('');
  const callbackHandler = (childData) =>{
    setText(childData);
  }
  return (
    <div style={{ display: 'block', 
    width: 700, 
    padding: 30
    }}>
        <Child parentCallbackFunction={callbackHandler}></Child>
        {initText}
    </div>
  );
}

export default Parent;

Here in Child component a prop is added (parentCallbackFunction) whose value is a function (callbackHandler), which will eventually be called from the child component.

<Child parentCallbackFunction={callbackHandler}></Child>

Child.js
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import 'bootstrap/dist/css/bootstrap.css';

const Child = (props) => {

  const submitHandler = (event) =>{
    event.preventDefault();
    props.parentCallbackFunction(event.target.tbox.value);
  }
  return (
    <div>
      <Form onSubmit={submitHandler}>
        <Form.Group className="mb-3">
          <Form.Label>Enter Value</Form.Label>
          <Form.Control type="text" name = "tbox" placeholder="Enter value" />
        </Form.Group>
        <Button variant="primary" type="submit">Submit</Button>
      </Form>
    </div>
  );
}

export default Child;
  1. In the form we have an input text box and a submit button. On clicking the button form is submitted which also triggers a submitHandler function execution.
  2. event.preventDefault() method prevents the default action from occurring which means on clicking the submit button form is not submitted to a server.
  3. props.parentCallbackFunction() method call results in the callback function execution in the parent. Here value of the text box is passed as a function parameter.
Child to Parent communication React

2. In the second example to show child to parent communication in React, we’ll have a ProductForm to fill product data and also a table to show the existing products and the table should be updated with the product added using ProductForm.

Data from child to Parent React

After clicking Add Product

The application is divided into 3 components-

  • ProductForm.js where user can enter Product name and price. In the form there is also a “Add Product” button which submits the form.
  • ProductItem.js which displays the list of products.
  • Products.js which acts as a parent component ensuring that the product added through the form is appended to the already existing list of products and the updated list is pushed to the ProductItem so that the newly added product is also displayed.

Product added using ProductForm has to be passed to the Products which is an example of child to parent component communication in React. Updated list from Products has to be passed to the ProductItem which is an example of parent to child component communication in React.

Products.js
import ProductForm from "./ProductForm";
import ProductItem from "./ProductItem";
import Table from 'react-bootstrap/Table';
import React, { useState } from "react";

// Initial list of products
const INIT_PRODUCT_CATALOG = [
  { id: 1, name: 'Laptop', price: 455.50 },
  { id: 2, name: 'Mouse', price: 15.89 },
  { id: 3, name: 'USB', price: 10.00 },
  { id: 4, name: 'HDD', price: 55.50 },
];
const Products = () => {
  const [products, setProduct] = useState(INIT_PRODUCT_CATALOG);

  const saveProductItemHandler = (productItem) => {
    setProduct(() => {
      return [productItem, ...products];
    });
  }
  return (
    <div className="container">
      <ProductForm onSaveProductItem={saveProductItemHandler}></ProductForm>
      <hr />
      <Table striped bordered hover size="sm">
        <thead>
          <tr>
            <th>ID</th>
            <th>NAME</th>
            <th>PRICE</th>
          </tr>
        </thead>
        {products.map((val, key) => <ProductItem key={key} item={val} />)}
      </Table>
    </div>
  );
}
export default Products;
  1. Here in Child component <ProductForm> a prop is added (onSaveProductItem) whose value is a function (saveProductItemHandler), which will eventually be called from the child component.
  2. The saveProductItemHandler function gets newly added product as a parameter and then adds it to the existing array of products.
  3. To the child component, ProductItem, data has been passed down using props. Here Array.map() method is used to iterate product array and in each iteration ProductItem component is called to display that row of product data.
ProductForm.js
import { useState } from 'react';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
const ProductForm = (props) => {
  const [pName, setEnteredName] = useState('');
  const [pPrice, setEnteredPrice] = useState('');

  const handleNameChange = (event) => {
    setEnteredName(event.target.value);
  }
  const handlePriceChange = (event) => {
    setEnteredPrice(event.target.value);
  }

  // Form submission handling
  const submitHandler = (event) => {
    event.preventDefault();
    const productItemData = {
      id: Math.round(Math.random() * 10),
      name: pName,
      price: pPrice
    }
    props.onSaveProductItem(productItemData);
    setEnteredName('');
    setEnteredPrice('');
  }

  return <Form onSubmit={submitHandler}>
    <h2>Product Form</h2>
    <Form.Group className="mb-3">
      <Form.Label>Product Name</Form.Label>
      <Form.Control type="text" name="name" value={pName}
          placeholder="Enter product name" onChange={handleNameChange} />
    </Form.Group>
    <Form.Group className="mb-3">
      <Form.Label>Price</Form.Label>
      <Form.Control type="number" name="price" value={pPrice} min="1" step=".1"
          placeholder="Enter price" onChange={handlePriceChange} />
    </Form.Group>
    <Button variant="primary" type='submit'>Add Product</Button>
  </Form>
}

export default ProductForm;

When the form is submitted submitHandler function is called where productItemData object is created using the entered values and the object is passed onto parent component in the props.onSaveProductItem(productItemData); call.

ProductItem.js
const ProductItem = (props) => {
  return (
    <tbody>
      <tr>
        <td>{props.item.id}</td>
        <td>{props.item.name}</td>
        <td>{props.item.price}</td>
      </tr>
    </tbody>
  )
}

export default ProductItem;

That's all for the topic Pass Data From Child to Parent Component in React. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment