React has been around for a long time, but it still remains a hot tech today. Take a look at the npm trends - React is way ahead of its competitors.
This means, more and more beginners start their framework/library path from React and many are getting lost when it comes to data flow in React. So, is it really hard? I don't think so and in this article, I would like to explain how I see React data flow.
React components architecture
Typical React component
So, what does a typical React component looks like? Well, pretty simple. Usually, it's a parent component that wraps one or multiple children. It looks something like this:
And, of course, it can be and is nested.
If you look at the typical React application, it's actually a lot of components that are nested inside each other. Every child component is a parent to their child components. In the illustration above Child Component 0
is actually a parent component for Child Child Component 0
. The flow here is pretty straightforward, right?
So, how do we pass the data between these components?
Props Mental Modal
React library is using unidirectional data flow architecture. Unidirectional means that data is going only in one single direction and in the case of React it's always going down from parent to children.
Let's think of the parent component as a pool with water, where water is different data that exists in the component. It can be data that was declared in the component, fetched, or imported from other modules, most importantly, if this data exists in the parent it can be shared with its children. Let's create a mental model of these relations and draw a parent component once again:
As you can see, now our parent has the pool of data and if you have to move the water from one pool to another, how would you do it? You will use pipes, right? Let's add data pools to our children components and draw a pipe that connects these pools together. We will use nested components as it's easier to understand the global picture:
Good, so now we have our data pools connected with a pipe, but we still can't pass any data, because we did not open valves to pass the data and receive the data. Let's do that!
Passing Props and Receiving Props
Computers are dumb, let's face it. By saying dumb, I mean that they are quite precise and do only what you tell them to do. In React, children are not aware of what's happening with the data that parent has until we allow it. And to allow it, we need to make sure that the parent indeed shares that info - passes data down to the child and that the latter actually is aware of it and receives it. Take a look at the code below:
const ParentComponent = () => {
const data = 'banana';
return <ChildComponent data={data} />
};
const ChildComponent = (props) => {
console.log(props.data);
return <div>{data}</div>
}
In the code above, we made parent pass the data
down and child is receiving the props
object, so it's aware that something should be received. Since props
is an object, we can directly destructure props
to get the data directly.
const ChildComponent = ({ data }) => {
// ...
}
Good! You have passed the data from parent to a child component! Congratulations! Now, let's continue building our "pool" mental model. We had the pipes, but they were blocked, let's transfer our knowledge from the code snippet above and add some valves!
The valves are what actually control if data is being passed down and received. For both the parent and the child we have to specify that the data is passed down and is received, only then we will be able to access it from a child component. Single pipe works for a single data instance. For example, if you want to pass multiple instances of data, whether it's a string, object, or function, you should create a new pipe.
Congratulations! You passed the handleClick
function and data
object from ParentComponent
down to nested ChildChildComponent
!
Problems
As you can see, this approach is not the best, because sometimes you have to pass some data from the topmost parent to let's say the most nested child, somewhere really deep, like 10 steps down. From what we have learned, you can't just simply pass it from the parent and directly receive it at the bottom of the components chain. You will have to make every component in the chain receive the data from their parent and pass the data down to their children. This can get really messy very fast. Luckily, this React team has created something called React Context. We will take a look at React Context in the next article!
Summary
React is a pretty straightforward components library, it has its quirks, but in general, the moment you understand the data flow and parent/child relations it will get much clearer! Always try to imagine and associate with something simple based on a real-life example π
If you like this series, leave a comment and share! I hope this was helpful and made a few things clearer! If you have more questions, you can DM me on Twitter @SergiiKirianov.
Write good code π€