How to send data from a child component to a parent component in react?
Tags: react, javascript, programming
Published: 2022-08-23 19:33:25

To reach this goal we have to be aware about two different functions in react, `useImperativeHandle` and `forwardRef`.
I will not explain what are this function individually, it is better if we see it as a group.

When we use `useImperativeHandle`, the code will work until you use `forwarRef` in the same component, you will see an error like this if you are not using it.

 ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cutl60xawwjah6gl4r64.png)

---

To have better explanation of how to do it, let's do some code.

Imagine you need a button and this button have to save the amount of clicks that the user presses but we have to access this information only with another button in the same page, so basically we will have something like this.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bd24u14h2jlozgjaq404.png)

First let's create the children component
```javascript
import { forwardRef, useImperativeHandle, useState } from "react";
import PropTypes from "prop-types";

const CustomButton = forwardRef(
  ({ className, action = () => {}, children }, ref) => {
    const [count, setCount] = useState(0);

    // we are returning a function inside the ref
    // to returning the count of clicks
    useImperativeHandle(ref, () => ({
      getCount() {
        return count;
      },
    }));
    return (
      <button
        className={`button ${className}`}
        onClick={() => {
          setCount((count+= 1)); // we count the clicks
          action();
        }}
      >
        {children}
      </button>
    );
  }
);
// This line is because we get a warning
// When we use forwardRef we always have to have displayName
CustomButton.displayName = "Custom Button";

CustomButton.propTypes = {
  className: PropTypes.string.isRequired,
  action: PropTypes.func.isRequired,
};

export default CustomButton;
```
If you notice in the `useImperativeHandle` function we are returning a function call `getCount()` which returns the amount of clicks, but now maybe you are wondering how to use this component. Let's create the parent component.

```javascript
import { useRef } from "react";
import CustomButton from "../components/customButton";

export default function Example() {
  // we create a reference to the first button
  const button1 = useRef();

  // function of the first button
  const onClick = () => {
    console.log("do some action");
  };

  // function of the second button
  const onClick2 = () => {
    // we get the count with the reference of the first button
    console.log(ref.current.getCount());
  };

  return (
    <>
      <CustomButton ref={button1} action={onClick} className="is-success">
        Button 1
      </CustomButton>
      <CustomButton action={onClick2} className="is-danger mt-3">
        Get count of button 1
      </CustomButton>
    </>
  );
}
```

As you can see, the function of the second button gets the count of the first button, but let run it and do some clicks and see the console.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2vxx98usjpy29z5uboz1.png)
The console says we have press the button 9 times, now let's press the second button.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ooe6k2vl3ubzjkvzo5r.png)
We get the amount successfully! But let's do some more to see if we still get the right answer. 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mic8gtjqc37gth2w1izi.png)

 
### Conclusion
We can return anything from our children components, like a function as we did, or objects, string, and if you want we can return elements of the DOM or even another references, the power of this is pretty amazing.
There is another approach of passing data from a children to a parent but this is for another post...

Thank you so much for reading and feel free to contact me if you need anything.