📓 4.2.2.3 Unidirectional Data Flow
So far we have only been working with local state. However, when a user inputs data in our form, we somehow need to get that data from our NewTicketForm component to its parent TicketControl component.
Before we do that, we need to learn more about unidirectional data flow. Unidirectional data flow is a language-agnostic term for applications that have data flowing in only one direction.
In the case of React applications, data can only flow from a parent component down to a child component. That's why shared state should always be lifted to a common ancestor. Only child components will ever be able to access that state. Components that are higher up the component tree (above a component with state) have no way to know about that state because of unidirectional data flow. In fact, components in React are so modular that they don't even know their parents exist. It's the job of parent components to keep track of their children, not the other way around.
The same is true with props. We can only pass props down from a parent component to a child component. That's the whole point of unidirectional data flow. It may seem like a limiting concept, but it makes planning, building, and debugging an application much easier. If state and props could flow in every direction, our applications would quickly become a mess.
So if data can only be passed down, then how can we get information from a child component up to a parent component?
The answer: we need to use callbacks. Here's how it works:
- We define a function in a parent component that has state.
- The parent component passes this function into the child component as a prop. Functions can be props just like any other data type.
- We call this function in our child component, passing data as an argument.
- When the child calls this function, the function in the parent component is invoked. Because the function lives in the parent component, the parent can access any data that's passed into it.
This may feel like we're breaking the rules of unidirectional data flow because the parent component can access information from the function call in the child component.
However, that's not the case. The parent component passes props down using unidirectional data flow. If a function is passed downward as a prop, the parent can still access it when it's called.
Understandably, this concept can be confusing at first. Let's make it more concrete by describing how we will do this in our Help Queue application. We'll do the following:
- First, we will create a function called
handleAddingNewTicketToListin the parentTicketControlcomponent. - Next, we'll pass this function to its child
NewTicketFormcomponent as a prop calledonNewTicketCreation. - Our child
NewTicketFormcomponent has a function calledhandleNewTicketFormSubmissionwhich correctly gathers user inputs from a form. We will callonNewTicketCreationinsidehandleNewTicketFormSubmission. - Form data will be passed into
onNewTicketCreationas an argument. - The parent
TicketControlcomponent will receive that data and use it to add a new ticket to ourmainTicketList.
Now that we've covered unidirectional data flow, we're ready to implement this new functionality. Don't worry if it still doesn't make sense. This is a new and complex concept for React beginners — the best way to learn and internalize how this works is to actually write the code — and then continue to practice working with unidirectional data flow until the underlying concepts begin to click.