Shopify App From Scratch #9 - React Sidestep 3
Tags: javascript, react, shopify, shopifyapps
Published: 2020-06-06 17:10:55

## Deprecation Notice

Yeah, yeah, I know. I hate it too when people abandon tutorial series mid-way. But, due to (exciting!) circumstances, I'm calling it quits for now.

I'm thinking of just dropping a link to the full repo here - it's a mess, but it's something you guys can chew on instead of my empty promises.

If you'd like me to drop it here - let me know at hey@redcaptom.com.

And, just sayin', I had a BLAST doing this. If you know something - anything - about technology, take the time to write it down as a tutorial series. You will get SO, SO much value out of it, you can't even believe it.

Until we meet again - RCT :)

## The Video (Scroll down for the article)

Coming soon!

## React class components

### Introduction
Generally speaking, you can get along in most simple React applications by just using functional components. If you need to keep some data that changes over the runtime of the application, for example, you can use the [`useState` hook](https://reactjs.org/docs/hooks-state.html). If you need to do something when a component was added, removed or updated from the application then you can use the [`useEffect` hook](https://reactjs.org/docs/hooks-effect.html). 

But, before React 16.8 ([which was released in February 2019](https://en.wikipedia.org/wiki/React_(web_framework)#History)), hooks were not even a thing. They became available only after that release, meaning that _before_ February 2019 you could not have state in a functional component, or know that it has mounted or unmounted. In practice, you used functional components for the "simple" stuff, and class components for the "complicated" stuff.

This is obviously no longer the case, but I still enjoy thinking in those terms. It offers perspective on what tools are correct for each job, and prevent you from over-complicating things with class components when you can just functionalize (is that a word?) your way to glory.

### Class Components Are Heavyweights
Class components are, from my perspective, a more heavyset version of functional components. They offer more fine-grained control over the component and are great as wrappers of functional components, but come at the price of more verbosity, a higher learning curve and less syntactic sugar than functional components. Let's take a look, shall we?

### A note about classes in JavaScript

I have to add  quick note on what a class actually is in JavaScript land: it's just a wrapper around existing JavaScript ideas, presented in a way that will appeal to Object-Oriented programmers. Put plainly - [JS Classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) are a way to define what a thing is, and then create occurrences of that thing in your application.

This means that you can define that class once, and then use it (the correct term is "instantiate" it) anywhere else in your application. In practice, we do not do that _directly_ in React - you do not instantiate the class component you create: React does that for you when it mounts the component. You can re-use the component in many places in your application, sure, but you can also do that with functional components, right?

This is confusing, and actually not very relevant if all you're trying to get is a grip on how React _looks like_ so you can pick up its ideas as you go along. For the sake of our discussion, then, I'm going to drop all reference to the _JS concept of a class_, and focus instead on _React class components_ only. If you're still interested, [dive into the docs](https://reactjs.org/docs/react-component.html) - they're really good.

## How Does One Identify A React Class Component In The Wild?

### The General Structure

Excellent question. I'm going to take an [example from the official React docs](https://reactjs.org/docs/state-and-lifecycle.html) and explain a little bit more on each part then they do there (although, if you come from an Object-Oriented background, you probably already know most of what I'll talk about):

```react
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);
```

This class renders a clock that displays the current hour in `HH:MM:SS` format to a page. Let's break it piece by piece, starting first with the virtual DOM rendering:

```react
ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);
```

We've seen this before, this is how we place components on the DOM. Let's disregard it, since placing components on the virtual DOM is the same in functional and class components.  Removing it, then, leaves us with:

```react
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
```

### The Breakdown
The first part of the component is its definition - `class Clock extends React.Component`. This just means we're using an existing thing from React - the `Component` class - as the basis for our class. This allows use to create our class by basing it on a set of features React offers in the `Component` class. Moving on:

```javascript
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
```

A `constructor` is a special function that is called when the class is instantiated - in our case, when the component is evaluated by React before being placed on the DOM. The `props` are the attributes we've seen passed to components in the previous example - e.g. in `<MainInfo participantName="tom"/>`, the `MainInfo` component's `participantName` prop has the value `tom`. The reason we're passing the props to the constructor is so we can have access to them inside the component - otherwise we will not be able to know that `participantName` had the value `tom` when the component is mounted, making it difficult for us to display it on the page, for example.

`super(props)` is another special function that calls the constructor of the _upper_ class our class is extened from - i.e. `React.Component`. We do that to make sure the concept of props works correctly in our class component, [as explained here](https://reactjs.org/docs/react-component.html#constructor). 

Finally, `this.state = {date: new Date()}` can be formatted a bit differently for better legibility:

```javascript
this.state = 
{
    date: new Date();
}
```

Which means we're assigning `this` - i.e. our class `Clock` - a property called `state` (yes, like in the `useState()` hook), that is a [JavaScript Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) that contains a single field `date`. We then set this field to contain the current date (`new Date()` returns the current date and time). So, what we're basically doing is initializing the state of the object with a single element - the current time.

This is a common pattern in class constructors. We can then change the state by calling a special function called `setState()` (more about it [here](https://reactjs.org/docs/react-component.html#setstate) - it works like the handler function from `useState()` we've seen in the previous section), and access any elements in the `state` of the class by using `this.state.X` (like in our example - more on this below).

Moving on:

```react
render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
```

This part determines what the component does - i.e. how it looks like when rendered. The `render()` and `return()` parts are just React's way of saying - this is how the component is going to look like when presented. The interesting part is the JSX (we talked about it previously) between the parantheses of `return()`:

```jsx
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
```

This is what the component is going to actually look like - two headers, the first of which is static and the second one referencing the `date` element in our `state`. Specifically, we'd like to extract the time in the user's time zone, which is what `date.toLocaleTimeString()` does.

Phew, that was a bit long, but I hope you got a good sense of what a class component looks like in practice. I'd like to make just a final note on lifecycle methods and nip this in the bud:

## The React Component Lifecycle 

We are going to add one small thing to our class component - a [lifecycle method](https://reactjs.org/docs/state-and-lifecycle.html#adding-lifecycle-methods-to-a-class):

```javascript
componentDidMount() {
    console.log("Clock has mounted, dude!");
}
```

So our full component is:

```react
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

componentDidMount() {
    console.log("Clock has mounted, dude!");
}

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
```

All this does is log a message in the console when our clock component is being added to the DOM (i.e. when it is _mounted_). These type of methods allow us to have a finer control of what happens when our component's status changes. Why is this useful, you ask? To me, it's kinda tricky to explain this out of the context of a full application. We will see an example of this being used in the final application I'm building in this series, but for now it's enough to say that it's really convenient to be able to know when a component has entered and left the DOM.

## Final words

This is all I have to say about React itself in the context of this tutorial. This is only the tip of the iceberg, as React is a somewhat advanced framework - but should give you at least _some_ intro into what it is you're looking at when reading React code. I do recommend you go buy [Dave Ceddia's Pure React](https://daveceddia.com/pure-react/?utm_source=tom) - it taught me most of what I use in my apps, and the guy is still updating it today! Hey Dave, if you're reading this, thank you for an awesome book! :)