Understanding unidirectional data flow in React

React is a popular front-end JavaScript library that many developers like because of its emphasis on writing reusable and modular UI components, as well as its insistence on one-way data flow. React, unlike Angular, has one-way data-binding. One-way data binding means that React is more performant than Angular and also makes debugging a React app easier than debugging an Angular app, in my opinion. A unidirectional data flow means that when designing a React app you often nest child components within higher-order parent components. The parent component(s) will have a container for the state of your app (typically an immutable variable called state, unless you are using Redux or Flux, in which case you would encapsulate your app’s state in a store). The parent component typically passes down a snapshot of its state to its child components via read-only props and then the child components can communicate with the parent to update the state via callbacks which are bound to a button or form in the child component.

Getting the hang of unidirectional data flow in React is something that took me awhile to wrap my head around, so here is a generic example loosely inspired by a voting app I am working on as a volunteer project:

Here you’ll see a gist that outlines the parent component of an app. The parent component is responsible for storing the state (in this case, the number of votes). The parent component passes this state information down to its child components, CandidateList and Candidate, via explicit props. The parent component also defines a function, handleVote, which is passed down as a prop to its children (yes, you can pass functions as props also!). The child components will then define a function callback that bubbles up to the parent to let it know when a user has voted for a candidate.

Parent component for React voting app

Here is a gist outlining one of the children components for our fictional React app. This component is called CandidateList and should show the user a list of candidates for a local organization’s election. Because I wanted to merely illustrate the general principles involved in unidirectional data binding in React, in this example we’ll pretend that there is only one candidate running for election unopposed so our state in our parent component can be relatively simple and have only two properties (candidate and votes) and pass this down to the CandidateList child component.

Child component for React voting app

As you can see from the above example, the parent component manages the state and keeps track of its data and also passes down the ability to vote for a given candidate (in this case, Sam Bee) via a prop bound to an onClick handler. Hopefully this example is somewhat illuminating for those who were as new to one-way data binding as I was when I first began developing with React.