React, Redux, and Redux Observables

The intention is that this will the first part in a series covering how to build end to end Single Page Applications (SPAs) using React. Since React is view only, other tools must be brought in. I will also be giving a talk based on this series throughout 2018, notably at CodeMash in a couple weeks to start. Without further ado, let’s dive in:

Part 1: React

React is a View framework created for highly interactive web applications by Facebook; in fact it is the main view engine for both Facebook and Instagram websites. The problem when creating highly interactive websites with JavaScript is we stress the DOM rendering engine heavily. Each time we perform any sort of manipulation, the DOM gets repainted. Modern browsers have learned to do this in smarter ways but the problem stil exists that as you have more happen, you start to see degraded performance,

To combat this, we started seeing the emergence of the “Virtual DOM” (https://www.npmjs.com/package/virtual-dom). The idea here is, we operate against this Virtual DOM which then calculates the delta’s from the DOM’s previous state and the target state and makes the changes in one fell swoop. The result is a cleaner separation between state tracking of the DOM and your application code.

React (and other SPAs) now build this is as part of their rendering pipeline, so you can take advantage of this with little effort. But before we dive too deeply into this, let’s get the basics of React covered.

React applications are composed of “components” which define view and interactive functionality. Currently there are two popular ways to create these components, each has its own place. (apologies as code samples need to be in images for JSX, WordPress apparently does not like the syntax)

The Class Component
react1

The Stateless Functional Component
react2

Now both of these will visually show the same thing however, there use cases are very different. But before we can talk about that we need to explore the idea of “state” in React applications.

In React applications, data (or state) can be passed around in two forms: state and props. I realize the terminology here can be a bit confusing. Its enough to understand that state and props are low level monikers for the notion of state. In particular, props represent readonly data that is passed into our component via attributes. state is read/write data that is held within our components proper. However, as the name implies Stateless Functional Components do no support the read/write state mentioned above, there are for presenting purely data the readonly.

To think about this another way. Let’s say you were designing a form to add something. You might create something like this to represent the entire form:
react3

In React, each of these would be a component, so we would, at the start have four components: The main component which holds our save button and hosts the other three, let’s call this FormComponent. The others are easy:

  • UserInfoComponent
  • WorkHistoryComponent
  • VideoGameCollectionComponent

Note: the suffice Component is not mandatory, its a convention that I have adopted that is useful when you start adding more complex things on top of React such as Redux, more on that in Part 2.

The tricky part is combining state and props correctly; its a fine line and can easily create clunky code if done incorrectly.  Here is how I like to think of it:

I use state when I want to save something in a temporary store. For example, if I am creating a new record, I would want to the data persisted while the user is on the form but, should I hit ‘Back’ or ‘Cancel’ I would want it to go away. In our example, state will exist in multiple places, but the be all end all state that we care about will live in FormComponent since it is this component which holds all of the others.

Props is data that is passed into components. It can be derived from state or it can become state; this makes sense as state is only ever internal to the control. Where this does get a bit weird is when we are communicating back. For example, assuming our “user” record we are creating this in FormComponent as such:
react4

Ultimately, this is the state variable that will get updated as data changes. But lets say, for this example, that a field UserInfoComponent called username existed and each time the react5user changed this value we wanted to update this user in state, how would we do that?

This is where things get a bit tricky. Two rules here:

1) A component should NEVER, but NEVER read state from another component. Doing this will cause you great pain and suffering in the long haul. Just dont do it.

2) Never, but never, mutate state. You will find this throughout the Redux pattern as well, but within the world of statement we always want to replace state, never mutate it in place. The reason is, by replacing we greatly decrease the chances of race conditions and side effects.

Okay, so with that out of the way, let’s tackle this. First, I am going to show the source for my UserInfoComponent:
react5

First thing I will point out is the top. In JavaScript if you have an object you a special syntax whereby you can have variables which are named the same as properties of a given object (I do this for username and usernameChanged). I realize that sounds complicated, but perhaps this will help. Here is what the object looks like without this:
react6

Notice in this example we are referencing the props parameter (Functional Stateless Components) are effectively functions, which is why they dont support state. In this case, the use of props vs { prop1, prop2, … } is irrelevant because the incoming parameter are so simple, but for more complex cases its a lifesaver.

Ok, enough of that, let’s talk about what is happening here. Our UserInfoComponent now supports two props:

  • username: The current value of username
  • usernameChanged: The function to call to update the username in the hosted components state. Remember, our UserInfoComponent does not have state, so we cant store what the user types within it.

Okay, so that is cool, let’s return to our FormComponent and see what is actually happening:
react7

Okay, that changed a lot. So, the first thing to point out is we have imported our UserInfoComponent from above. We can see that we are passing local elements in for the username and usernameChanged props; note these names do not have to match, can be anything you want. The definition of these attributes hydrates our props object.

So when the user presses a key in our textfield, locally it will call onChange. That onChange method will extract the updated value our textfield and pass it to the func which was given through the usernameChanged prop. When this is called it will execute the usernameChanged method in the above code sample.

Now, this method is topic in and of itself. Remember, we said you CANNOT mutate state, you should always replace it. To facilitate that, you will find yourself using Object.assign a lot (docs for Object.assign). What this does is it takes a target (first parameter, in our case an empty object) and combines it with a second (usually an existing object, in our case the current user in state) and a third (the changes that should be made to parameter two as the final result is created). The outcome is a brand new object which we can use to replace the existing object.

After we have that object we call the special setState method which recreates the state based on our state changes (again, we are REPLACING state, not modifying it. That distinction is vitally important). Once setState is finished, the component will re-render itself with the new state values.

Understanding this cycle is VERY important to the React programmer as it underpins EVERYTHING. Failure to understand it can result in hard to manage state and flow. Facebook designed React to be cyclical in its nature, which makes state management easier. With strict rules to negate potential misunderstanding.

Getting Started

So, now you have a basic grasp of React and how it works to deliver highly functional and performant views. But as is the case with modern frameworks and tools, it can take a lot ot get going. Luckly, Facebook has created the create-react-app package which offers a command line interface to getting started, details here: https://github.com/facebookincubator/create-react-app

One side point about this, the tool is awesome as it bundles everything from server setup, file watching, Babel and Webpack into a single executable that anyone can run. However, it is not awesome for the same reasons. Luckily you can “eject” if you want to take a more heavy handed approach to configuration. Its documented to explain the risks associated.

Next Steps

In the above we got you going with an application but, its pretty useless as you can only collect data into the state of FormComponent. What do you do after? That is where we move to the next topic: Redux, specifically React-Redux

2 thoughts on “React, Redux, and Redux Observables

Leave a comment