DEV Community

Cover image for How to pass props from child to parent component in React
Bruno
Bruno

Posted on

How to pass props from child to parent component in React

You have probably been passing props from parent to child components, and you have questioned yourself: "Hmm... but what if I want to pass props from child to a parent component? I mean... the other way round?", right? πŸ€” I have also questioned myself that, but there are solutions actually.

harold and old woman from creepshow 2019

We will go through them.

What is the typical flow of props?

The typical flow of props is from parent to child. Basically, let's say you have a Parent component which looks like this:

parent component code snippet

The child component we have below uses a Button component from the very much beloved shadcn/ui component library. The Button component has a children prop, which is passed from the Parent component.

child component code snippet

Above, we are passing a children prop from the Parent component to the Child component. All good so far, right?

What if we want to pass props from child to parent?

Now, this is where things get a bit tricky, espcially if it is your first time implementing such logic. The tricky part about it is probably not how to go about doing it, but more how to visualize it. Either way, I have been there, and my experience will hopefully help you out 😌

crafting things

Because learning is best done by doing, let's bring the example from earlier, and modify it a bit to see how we can pass props from child to parent. The goal of this example is to show how we can modify the state of the Parent component by passing data from the Child component.

parent component code snippet

And here is what we do from the Child component:

child component code snippet

Making it simpler to understand in written form, what we are trying to accomplish with the two components is that we initialise the state in the Parent component, and then pass the variables down to the Child component, and the respective function to update the value of the state in the Parent component. In this case, suppose the value of the state is first set to false. When we click on the button from the Child component, it will take that value, and change it to the opposite of false (! in the value negates it) when the function gets called on the click event.

A common pitfall while passing data from child to parent

Passing data from the child component to the parent does have its quirks. One of the most common pitfalls is forgetting to pass the callback function as a prop to the child component, but that also means that you are passing more logic that you you need to pass. This can lead to more annoying, and harder to debug bugs.

on fire meme

One way to prevent this is to use the useCallback hook, which makes sure that the function you pass as a callback to the child component remains stable across renders, preventing unnecessary re-renders and improving performance. What happens with useCallback is that you pass a function as a prop to the child component, and the child component will have access to the function, and can call it when needed. Let's see how we can do this.

useCallback example code snippet

Now let's show how it looks like in the Child component:

child component using useCallback function code snippet

Isn't this cleaner than passing the function, and then updating it from the child, and then passing again to the parent? Cleaner, and easier to implement, too, right? 🀩

Thank you for reading!

Even though there are surely more, and potentially even cleaner, better-looking ways of passing data from child to parent in React, I hope that after reading my article, you will find it easier to understand the flow of how data passes from child to parent, and how to go about implementing that with two different ways. Who knows, maybe you will find a more creative way of doing it yourself? πŸ˜‰ If so, it would be greatly appreciated to explain your ideas in the comments!

About the Author

I'm a software developer, and technical writer based in Portugal. I'm passionate about software engineering πŸ‘¨β€πŸ’» and I love to explore new tools in my day-to-day, and find interesting, and creative solutions to common business, and techincal problems. You can find me on GitHub. If you have any questions or feedback, feel free to reach out! πŸš€

Top comments (10)

Collapse
 
alban_b_3bf6fa8c9028372f profile image
Alban B. • Edited

Hi Bruno, thank you for the great post. I am doing something similar, and finding myself lost in the syntax. I have been able in the past to pass values as props from Parent to Child components, as well as implement your callback solution.

I was wandering what would be the correct syntax to (lets say by making it analogous to your example):

  • Pass isOpen as a prop from the Parent, and be able to access it from the Child component;
  • Pass handleOpen as a function, alongside the first prop;

I tried:

const Child = (props, {handleOpen }) => {}

...but in this case handleOpen is not recognised as a function.

Keep up the good work and thnx in advance for your time.

Regards

Collapse
 
bcostaaa01 profile image
Bruno

Hi Alban, thank you for positive feedback and for reading this post. I hope it was helpful to you somehow.

As for the syntax, there are two main ways you can get access to the handleOpen function in the child component:

  1. pass only the main props to the parameter

  2. destructure the handleOpen and use it in the child component

Why you can't use the syntax you tried is because React only gives you the props object, so you can only use one of the two, but never props and handleOpen in the same function definition (adding both as arguments basically).

It is a bit of a confusing approach probably, but basically you either use one approach or the other if you want to access the handleOpen in the child component.

Collapse
 
sujay_explorer18 profile image
Sujayweb3master

The right syntax is:
const Child = ({handleOpen}) => { }
Props are always passed as a single object, so destructuring should happen inside the first parameter itself.

Collapse
 
bcostaaa01 profile image
Bruno

Right, and ambiguous at the same time. Like I explained in my response, you can use either of the two approaches. None of them is "right" or wrong. If you want to pass only a specific prop to the child component, then use the second approach and specify the prop with the destructuring, otherwise use the first approach if you want to pass a collection of props or pass them to other components. Be careful with saying something is right or wrong when there are multiple approaches available.

Collapse
 
brense profile image
Rense Bakker

I like how you also explain the merrits of using useCallback in this case! Btw if the child component doesnt depend on isOpen you can prevent it from rendering by removing the isOpen dependency in the callback:

const handleOpen = useCallback(() => {
  setIsOpen(isOpen => !isOpen)
}, [])
Enter fullscreen mode Exit fullscreen mode
Collapse
 
bcostaaa01 profile image
Bruno

Thank you for the positive feedback, and for the suggestion, Rense! Much appreciated, and good point for sure :D

Collapse
 
oatula profile image
Atul Anand Oraon

πŸ‘ Nice.

It would be nicer using useContext()

Collapse
 
bcostaaa01 profile image
Bruno

Thank you for your positive feedback, and the interesting suggestion! That definitely deserves an article of it’s own.

Collapse
 
hututuhu profile image
hushanqing

great post!

Collapse
 
bcostaaa01 profile image
Bruno

Thank you so much for the positive feedback!πŸ˜ƒ

Some comments may only be visible to logged-in visitors. Sign in to view all comments.