React is a popular JavaScript library for many reasons and one of the reasons is “one-way data binding”. If you want to understand React to its core, you should read along.
It’s a one-way road for the data
React apps are made up of carefully organized components. These components receive arguments(props) and return information using the return value of the render function. When data flows from the parent to the child component, it is known as the unidirectional flow of data.
Parent component passes information to child component using props. But it is also possible that a child component might end up requiring to change something in the UI. What to do in that case?
Is it possible to pass data from the child to parent component?
What if clicking a button in the child component changes the text in the parent component? How do we make sure that the parent component is aware that a button is clicked that is supposed to change its text?
This is achieved by the parent component by passing a callback function as a prop when calling the child component. The child component now calls this function when the button is clicked. This provides the parent component with all the required information about the state of the child component or the user actions.
Example
Before anything else, it is essential to understand which UI component should be changed based on the user input. This is where the concept of “state” comes in.
As we already discussed, we need to change the text in the parent component that is currently “Hello” to “World”. So, that is our element of the state.
Now, which component should the state live in? The child? The parent? Um.. so here are a few steps that would make it easier for you to decide where the state should reside:
- See which component renders something based on the state.
- Identify the highest component in the hierarchy that relies on the state.
- The state lives in either the highest component in the hierarchy or some other higher component.
- If you are unable to find a component worthy of owning the state, you can create a completely new component whose whole purpose is to hold the state. Then you can add this component as the highest component in the hierarchy.
In our case, it is easy to identify that the state should reside in the “Parent” component.
const [text, setText] = useState(“Hello”);
Now, what do we do to the “Parent” component? We pass the callback function as a prop from the parent component.
<Child changeText={(text) => setText(text)} />
Now we need a callback function in the “Child” component that is triggered when the button is clicked.
<button onClick={() => props.changeText(“World”)}>
With all individual elements in place, here is what the JavaScript files look for each component:
Parent.js
import React, { useState } from “react”;
import Child from “./Child”;
function Parent(props) {
const [text, setText] = useState(“Hello”);
return (
<div>
<h1>{text}</h1>
<Child changeText={(text) => setText(text)} />
</div>
);
}
export default Parent;
Child.js
import React from “react”;
function Child(props) {
return (
<div>
<button onClick={() => props.changeText(“World”)}>
Change the text
</button>
</div>
);
}
export default Child;
App.js
import Parent from “./Parent”;
function App() {
return (
<>
<div className=”App”>
<Parent />
</div>
</>
);
}
export default App;
How does it work?
In the “Parent” component, the content inside the heading tag is supposed to change, initially, it is set to “Hello”. Now when the button(in the child component) is clicked, it triggers the onClick event listener that calls the callback function passed from the “Parent” to the “Child” component, which changes the text to “World” and re-renders the component.
Conclusion
React follows the unidirectional approach, meaning that data flows from parent to child and not vice versa but if you really need to manipulate your parent component based on something in the child component, you can use a callback function and pass it as a prop from the parent to child.
This function updates the state in the parent component and once the state is changed, it passes down as props again. This allows the components to re-render and display the required results.
Here I explained passing data from child to parent component using functional components, the same can be achieved using class components as well.
Top comments (29)
Hi Parnika. Nice Explanation. But I think the heading is a little misleading. You mentioned about one way data binding in React and the article is about Unidirectional Data flow in React. Both are two different things.
One way data binding happens on the component level. Where the Component UI is connected and synced with the Component state.
While Unidirectional Data flow is about passing data from Higher component to lower component in Component Hierarchy.
Just what I was looking for! Thanks a lot Anurag!
This statement made my life is easy on React. I was so confused about these 2 statements one way data binding and unidirectional data flow next tow way data binding and bidirectional data flow. Thanks for your comments. If possible could you please provide the examples of one way data binding and two way data binding in React.
One way data binding happens when you declare a variable with a value and attach that variable on the UI.
As you see in the above example, I have a variable with value anurag which I am putting on the UI. The variable is attached to the UI and not the other way around. The user cannot change the value of the variable. This is one way binding - Data to the UI.
In two way data binding, the user can change the value of the variable through some action performed on the UI. Something like a form or button.
So In short, if the Logic defines the value present on the UI, it's one way binding. If the logic defines the value on the UI and the UI can also update the value, it's two way binding.
I’m curious as to why you passed a callback to the child instead of just directly passing the setText function
Hey there is no particular reason I did that. Is there a reason why we should or shouldn't be using arrow functions when we can directly pass the setText function? I would love to learn more about the depth of it.
IMHO, its just matter of simplicity and consistency.
CMIIW.
I just saw a video on callbacks that made it clear for me.. I will find it again to grab a link and share if anyone needs...But what's the difference between 2nd format and the 4th one that you have shared?
I’m not actually sure. I’ve just always done it like this, but I don’t really see any differences between the two methods
The setText is a useState function, calling in somewhere is won't change the state, you have to call it in it's own component for it to work.
so he is returning the setState with the new value of text from the child to the parent which will now bw executed in the parent.
Hello @parnikagupta ,
What do you think of this ? :
Only to see that there is a life outside React :-)
In case you are interested how this works, you can give an eye here : DML
You can try it here : ParentChild
Regards
Nicely articulated. Congratulations on your first post.
It is worth to note that this holds good to any level of nesting of the components however not advised :)
Such situations can be dealt beautifully with Contexts or state management libs.
Thank you Rahul! Means a lot. But this is sort of my 2nd post but this one has reached more people, I guess people liked it better than my previous one 😜
Thanks for the additional information I have added it to my knowledge of React now! Really appreciate it.
For the syntax highlighting add the type after the first three backticks
Thanks Mainak! Will take care of it going forward.
Why there is no syntax highlighting in your code snippets?
Sorry I am new here so I am not familiar with formatting. Will improve in next one for sure!
Don't be sorry. I'm new too, and barely found out about syntax highlighting! ✌️
PS+
You can totally go back and edit your post and add
javascript
immediately after your first three back-ticks 😀Also, awesome article 👋
That's great will go back and do that right away! Thank you so much.
This was the first article without syntax highlighting I saw. I just assume it was something done automatic like on Stackoverflow. I learned about this recently myself.
Thanks for pointing it out though! Helped me learn a new thing. :)
Ah! Thanks for calling that out I copied the working code from my VS Code but I was deleting some experimental divs I was adding so must have deleted the div closing tag by mistake! I will just correct it in a sec.
Great article. Thanks @parnikagupta .
Thank you @alexandrefuente means a lot!
wonderful article
Thank You!
Simple and useful
Thank you so much!