React

Dec 10th 2019 by Mattes Wieben

Introduction

“Any fool can know. The point is to understand” (Albert Einstein). 

In this article you won’t find lots of code or the link to a GitHub-Repo which you can checkout to have a running Hello-World application. Neither will this be a documentation of Reacts API. That’d be pointless because the React docs are awesome (https://reactjs.org/docs/getting-started.html).

So, what is this article all about then? We will cover and explain the building blocks of react. We will dive into how they integrate with one another. And we will figure out how and when to use React. Therefore, in behalf of Mr. Einstein’s quote, the goal is to understand React and not to know a couple of lines of React code. And if you’re a React pro already, the goal is to teach me all the stuff, I got wrong :)

<sellout>

If you’d rather learn by coding, my next blog post will have you covered.

</sellout>

Sellout

Ok, ok ... back to the topic

Facts

Basics

Let’s start with some Facts about React. I’ll keep the basic-stuff as short as possible. Promise. React is a JavaScript-Library developed and maintained by Facebook. And yes, Facebook itself is developed using React.

It has been released in 2013 and its popularity has grown ever since. Today, with 135K Stars, it is number 4 of the most-starred-GitHub Repositories, according to gitmostwanted.

What is React and Why?

Short answer: React allows you to easily build component-based UIs, that run anywhere.

A little longer answer: React is library, which lets you compose complex UIs based on small, simple, reusable, easy-to-maintain components. Furthermore, React lets you add community-packages for anything logic-related like State-Containers with Redux, FormCreators Formik or http-handlers Axios. Through its usage of props and state (see later) React very much prefers immutability and forces you to think about where your application state should live.

WTF

If that sounds weird right now, read ahead. It’ll get clearer very soon.

Not a Framework

Something you’ll read very frequently when you read about React is, that it is a Library, not a Framework. The awesome Martin Fowler nails the difference with this picture:

Framework vs Library

Source: https://www.programcreek.com/2011/09/what-is-the-difference-between-a-java-library-and-a-framework/

It’s all about the Inversion of Control. 

  • A Framework on the one hand takes the control of the application and expects specific startup-behaviour, component-behaviour and component-communication.

  • A Library on the other hand is a collection of reusable Code-fragments that you may use as you like.

We should keep that in mind when working with React. We tell React where to hook in and we use the code of React, not the other way around. It is 100% up to us, how we start and structure our application.

Furthermore it is 100% up to us, whether we want to built our whole application using React or if we want to build an application, that is extended by one or two React-Components. However, in the “React”-Parts of our application we have to play according to React’s rules.

Immutability

When using React, you should always keep the immutability of data in mind. There are a lot of advantages of this Immutability-Pattern.

  1. It’s easier to detect changes. Consider the following-object: { ‘name’: ‘CodingKid’, ‘maxStatementsPerMinute’: 15}. If we treat CodingKid as a mutable object and change the maxStatementsPerMinute to 20, the old object is lost. It’s plain and simple a loss of information. We don’t know if he improved or not. Furthermore it’s harder to keep track of changes. If we on the other hand just created a new object with the updated value and add it to an array where we store all states of the object, it’s a lot easier to see when something changes. And we don’t lose information.

  2. Also, we achieve better encapsulation and therefore better testability of our code. Whenever we pass a variable around, we can be sure it stays the same.

  3. Last but not least React uses this feature to determine, when re-rendering is necessary. Whenever any part of your application's state is changed, React automatically re-renders everything that got out of sync. Rendering is non of your business anymore. Pretty awesome.

Of course, there are plenty more, but that’s not the main point here.

Usage

Basically, there are four ways, in which we can use React in our projects:

  • Developing a Single Page Application (SPA) using React

  • Extending an existing Application with Components developed with React

  • Pre-rendering a React-App on the server using Node

  • Using React native to create a mobile application

The first two possibilities are very similar, we’ll have a look into the differences in the next Chapter. They have in common that you create a Web-Frontend Application.

React does not require you to use any specific tech-stack. The most common Stack containing React, that crossed my way is the MERN-Stack (MongoDB, Express.js, React, Node.js). Maybe you have read that in one of my Instagram posts lately (if so, you're awesome ❣️)

  • MongoDB: “MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era.” (Link: https://www.mongodb.com/de). Nothing to add really ...

  • Express.js: “Fast, unopinionated, minimalist web framework for Node.js” (Link: http://expressjs.com/). Basically, it lets you build a lightweight REST-APIs.

  • React: Well ...

  • Node.js is a JavaScript runtime built on Chrome’s V8 JavaScript engine” (Link: https://nodejs.org/en/). Basically, it lets you run Javascript on the server.

But using those technologies is not a requirement by any means. We may just as well built a Java-Backend using Spring Boot, a Python Backend using Django, or … whatever appeals to us. 

Using Node to Pre-render your React-application is kind of a special case. For now, we should just know, it’s possible. If you want to know more about that, let me know. I might dedicate a future article to that topic.

React native is a framework for developing mobile applications (iOS and Android) using your React Skills. We won’t get take a deep dive into that topic today either. But in the future we will for sure. Just keep in mind that everything you learn today is applicable to building Web-Apps, Android-Apps and iOS-Apps.

Elementals

Now let’s get into React for real. What is React made of? How does it work?

Elements

Elements are the smallest, most basic building blocks of React. Even though React-Elements look a lot like DOM-Elements, THEY ARE NOT! Here is an example:

const element = <div> CodingKid is my favorite coding hero! </div>

Since React-Elements are plain JavaScript-Objects they are a lot faster to create than DOM-Elements. To clarify that, the previous line of code does the same as:

const element = React.createElement(“div”, null, “CodingKid is my favorite coding hero!”, null);

The difference is, that the first line is using JSX, React’s JavaScript-Extension which we’re going to cover in the next section. 

So, when we are working with React-Elements, we are actually working with JavaScript Objects. Those objects are describing, what the UI should look like. React interpretes this description and maps those JS-objects to DOM-Elements and updates, creates or deletes only what’s necessary to make our application as fast as possible.

☝️Remember☝️:

  1. Elements are the most basic building blocks of React-Apps.

  2. Elements should be defined using JSX.

JSX

As mentioned before, JavaScript XML (JSX) is React’s language extension to JavaScript. Facebook describes JSX as “a way of writing XML/HTML in JavaScript”. The purpose of JSX is to enable developers to use markups in a fully powered JavaScript environment.

This feature leads our code to be separated by concerns rather than technologies. That means that we may have mark-up, styling and logic of p.e. a button at one specific point in the code. We don’t need to split those things in a markup-file, a styling-file and a logic-file. It should be mentioned though, that styling can - and for the most parts still should - be separated in its own file.

One example of the would be the following:

function getFavoriteHero() { return “CodingKid”;}

const element = <div> {getFavoriteHero()} is my favorite coding hero! </div>

We could find those two lines in a single JS-file. The curly braces in the element-definition empower us to use any expression defined anywhere in our code.

☝️Remember☝️:

  1. JSX is a JavaScript-Extension.

  2. JSX is used to define React-Elements.

  3. JSX calls the React.createElement-Method to create the elements.

Components

By now we know, how to define the smallest building blocks, React-Elements, using JSX. But …

  • What if we want to make them reusable

  • Do we have to specify each element of the UI in the same place?

To answer these questions, we need to introduce the concept of components. Components split the UI into small, reusable parts. They group together some elements, capture state and define behaviour. Also, components themselves can become elements of their parent components. 

Conceptionally, components are pure functions in respect to their props (see below). They get values and/or functions as inputs and return a React-Element as output.

We’ll understand components in two steps. First, we are having a look at the building blocks of components to answer the questions where state lives and where behaviour is defined. Secondly, we’re having a look at different types of components to answer the questions where they differ and when to use which.

Building Blocks of Components

Render-Method

The render method is the single method that React calls on your components when it is about to re-render. A humanised dialogue might look as follows:

“Hey Component, React here. I’m about to re-render. How do you want to be displayed”.

“Hey React, Component here. I want to be displayed as this element.”

The render-method returns exactly one React-Element. This is a leightweight way to describe, what needs to be displayed to the user. Using this return value, React checks if there are any differences that actually require a re-render. If so, React figures out, which DOM-Elements are affected and updates them.

Remember:

  1. The render-method is called by React when a re-render is about to happen.

  2. A single React-Element is returned.

  3. The React-Element of (2) is describing how the component will be displayed.

Props

Props are arguments that can be passed from a parent component to a child component. We pass:

  1. Parts of the parents component’s state as variables

  2. Event-Handlers as functions

to the child component.

☝️Remember☝️

  1. Parent-Components can pass values to their children using props.

  2. The props-object can contain variables and functions.

State

The state is an object that is initialized within the constructor of a component. It is private to its creator. However, it may partially and immutably be passed to child-components as props. 

We may NEVER change the data in the state object. We always HAVE to call the setState method. Calling the setState method will tell React that the State changed. React will then initialize a re-render. If we didn’t call the setState method, React might miss the change of state and an update might be lost.

☝️Remember☝️:

  1. The state of a class-component is initialized in its constructor.

  2. The state-object is private.

  3. Never modify the data directly; always use setState().

Types of Components

Class Components

Class components are ES6 classes deriving from React-Component:

  • the props are passed into the constructor. And we have to pass them onto the super-class

  • the state may be defined in the constructor.

  • a render method is defined and returning a React-Element.

Additionally, we may add any kind of functions, internal behaviour and so on. Anything that could be added to a normal class as well.

Function Components

A Function component is a simpler way of writing a component with only the render method. It cannot contain a state. At least not per se. React Hooks were introduced a couple of weeks ago. They allow you to hook into the overall React state from within a function component. But that'll be the topic of another post.

☝️Remember☝️:

  1. Two ways to define a component:

    1. Class (can have state)

    2. Function (cannot have state)

  2. Convention: Their name - class or function - should by convention always start with a capital letter.

Event Handling

There is nothing really special about this. In comparison to handling the events of DOM elements, there are only small changes:

  • Firstly, React uses camelCase (onClick instead of onclick). 

  • Secondly, React passes a function instead of a string.

And that’s about it. Besides that there are only two more things, that we have to remember when working with event handling in React.

  1. We cannot return false to prevent default behaviour. Instead, we need to explicitly call the preventDefault-method on the triggered event.

  2. Context is always a thing in JS. If we need the context of “this” in the callback, we need to bind this to the callback method before it is called.

☝️Remember☝️:

  1. Pass a function as event handler.

  2. If necessary, bind this to the handler function.

  3. Explicitly prevent the default behaviour.

One-way Dataflow

It is important to understand, that React implements one-way dataflow. What does that mean? We learned that the state is private to its owner-component and therefore may only be changed by yonder. We also learned that parts of the state may be passed downwards to child-components as immutable props.

Now, let's consider a simple counter example with a label and a button.

We have a parent component containing two children, the label and the button. The value of the counter need to be displayed by the label and changed by the button. Therefore, we’d keep it in the state of the parent and pass it as props to the label. That’s the one-way dataflow, described above. 

But how does the button modify the state? It does not! The parent component needs to pass a callback to the button which the button will use as the event-handler for its clicks. Both child-components become fully controlled (state and function) by their parent component.

We can see, that the components can also communicate changes upwards in the component hierarchy. But this way has to be implemented explicitly. This way we need to write a little more code. On the other hand we gain the advantage that the state only lives in one place which avoids a lot of bugs. And if we manage to implement a bug anyways we immediately know, where to fix it.

☝️Remember☝️:

  1. It’s good practice to keep shared state in the closest common ancestor.

  2. State is private and only modified by it’s owner-component.

  3. The dataflow upwards has to be coded explicitly using event-handlers and callbacks.

React 201

So far, everything we’ve covered is part of the React-Library itself. Considering that React is a UI-Library on the one hand and is also used for developing SPAs on the other hand, one might wonder, how to realize stuff like business-logic-implementation, network-calls and testing the latter two. There are tons of community libraries out there that help you out. We’ll cover those topics soon

Summary

As always, thank you so much for reading. I hope you learned something and that you are a step closer to understanding React instead of only knowing it. If you did enjoy reading, you’d help me a lot with leaving a comment or sharing this post 😊

In case you found anything incorrect or anything that should be added, don’t hesitate to drop a comment either. I’d be happy to learn a thing or two and optimize this article. Also, I’d be glad to tackle any questions that might have been left unanswered.

And last but not least… If you’re interested in some more advanced React-topics, let me know. My writing schedule isn’t 100% fixed. If there is anything that would help you the most I might take that into consideration.

If you’re interested in learning React hands on, go ahead and check back in a couple of days.

Share this post