Forward Advance Learning

Vanilla React Components

So far we have created elements and appended them to the DOM. We could do this with jQuery. The real strength of React is its component driven architecture. Components are objects that let us ball up templates, state and behaviour. They are effectively new DOM nodes.

Understand this: Writing React means creating components. Components work like new DOM nodes. We build our app out of a tree of Components, nested one inside the other, in exactly the same way we might build a web page. We call this a Component Oriented Architecture.

There are two types of component:

  1. Stateless - fast components that do nothing except render data. They are simple functions that render bit of DOM.
  2. Stateful - slower, class-based components, which can have methods, and can hold their own data, but are slower in most cases.

The React way is to use stateless components wherever possible. Much more on this later.

Stateless Components

The simplest type of component is just a function that returns an element. This type of component should be preferred because in almost all cases it will be significantly faster. We'll look more at performance later. Stateless components are easy to reason about, are closer to idiomatic JavaScript, and are currently Facebook's recommended way of using React.

Because they are just functions, they don't hold any persistent data. They just receive information from their parent (via props, more on this soon), and render that information.

Notice how we can use React.createElement to create the Component and the h1. As far as React is concerned, conceptially, components are DOM elements, no different from divs and h1s.

See the Pen React Vanilla Component Demo by Nicholas Johnson (@superluminary) on CodePen.

We can use an ES6 fat arrow function to simplify this even further:

See the Pen React Vanilla Stateless ES6 Component Demo by Nicholas Johnson (@superluminary) on CodePen.

Change the text in the component. Create to a Goodbye component, and update the render to use it instead.

Stateful Components

A component can also be an ES6 style class that extends React.Component. In JavaScript, a class is simply a constructor function, i.e. a function with a prototype attribute that writes to this.

Creating a component as a class gives us more capabilities, at the expense of significantly greater overhead in terms of speed and memory. The generated object can hold its own persistent data, callback methods for events, and can manage its lifecycle if necessary.

Note that ES6 classes are understood natively in most current browsers. To support older browsers, we use a transpiler like Babel. More on this in the next section.

Here is a component declared as a class:

See the Pen React Vanilla Component Demo with ES6 Classes by Nicholas Johnson (@superluminary) on CodePen.

Create a GoodbyeComponent as a class, and render it.

A component has a render method, and perhaps other methods too that we will define. We can also hook into the lifecycle callback methods, to execute code when the component is created or destroyed, and we can override shouldComponentUpdate to optimise our rendering cycle. More on this later.

Nesting Components

Once declared, components can be rendered just like regular DOM nodes using React.createElement.

See the Pen React Vanilla ES6 Nested Component Demo by Nicholas Johnson (@superluminary) on CodePen.

Add a navigation component to the header. Add a copyright message to the footer.

Exercise - Legendary Heros

Assume I have an object that represents a legendary hero of old, something like this:

const hero = {
id: 2,
name: "Haldane Rendall",
type: "Swordsman",
maxHp: 36,
hp: 36,
armour: 33,
attack:12
}

In your browser, create me a component that will render this doughty warrior. Your index.html file will look like this:

<!DOCTYPE html>
<html>
<body>
<div id="app"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.min.js"></script>
<script src="app.js"></script>
</body>
</html>

It's up to you to write an app.js to handle the problem.

Extension

Create suitably heroic header and footer components to match.