1. Learn
  2. Learn React By Itself

React's Most Basics

At its core, React is just JavaScript. It doesn't need a build system or fancy syntax. And with just two functions, it lets you create something amazing...

James K Nelson

James is the editor of React Armory, and has been creating things with JavaScript for over 15 years.

Read more by JamesFollow @james_k_nelson on Twitter

So you’ve heard all the fuss about React – apparently it’s the best thing since Visual Basic. But you’ve spent a couple hours investigating, only to find so many buzzwords that it just feels overwhelming. NPM and Redux and Babel and react-router and Webpack and all I want is somebody to just tell me how to use React already!

Luckily for you, that’s exactly what this guide will do! Don’t believe me? That’s OK – you will after you’ve built your first React app in only 2 minutes. Without downloading or installing anything. Just by following this exercise…

Your First React App

Are you familiar with HTML, CSS and a little JavaScript? Great, that means you can write a React app!

In this exercise, you’ll use React to add some content to a blank page. But instead of starting by creating a HTML file somewhere, let’s have a little fun.

See the code below? This isn’t just any old code block – it is an editor that gives you instant feedback as you type.

Try it out by changing the blue number 0.01 (next to sprout) to something else like 0.15. You can also click “Start animation” in the Preview pane to animate the tree; try starting the animation after setting new values for sprout and sway.

import { PythagorasTree } from 'react-armory-pythagoras-tree'

ReactDOM.render(
  <PythagorasTree
    // Try changing `sprout` from 0.01 to 0.2
    sprout={0.01}

    // Try changing `sway` from 0.04 to 0.3
    sway={0.04}
  />
  ,
  document.getElementById('app')
)

The tree is based on @swizec’s fractal tree. Thanks!

By the end of this guide you’ll be able to create this tree all by yourself! But let’s not get ahead of ourselves, you still need to complete the first exercise. So without further ado, your task is to remove the <PythagorasTree ... /> tag in the above editor, and replace it by typing out the following:

<a href="https://xkcd.com/221/">
  <img src="https://imgs.xkcd.com/comics/random_number.png" />
</a>
Important

Why type it out instead of copy and paste? Well, typing forces you to process each of the individual commands. It drills them into your head in the process. Copying and pasting just gives you a short feeling of cleverness and a little dopamine. And if you just want dopamine, quit reading and play flappy bird.


Did you try the first exercise? Then Congratulations! You’ve made a React app that renders a comic inside a HTML page (you can see the HTML by clicking on the “HTML” tab). It should look something like this:

ReactDOM.render(
  <a href="https://xkcd.com/221/">
    <img src="https://imgs.xkcd.com/comics/random_number.png" />
  </a>,
  document.getElementById('app')
)

document.getElementById('app') returns an object called a DOM Node that lets us interact with the HTML element with the id app.

Read more at MDN.

But this exercise was pretty simple. All you did was render an image to the screen. The interesting part is in how you did that. In particular, how do the tags work? They don’t look like JavaScript?

JSX converts to JavaScript

Actually, the tags aren’t JavaScript. Instead, they’re converted to JavaScript by a tool called JSX. For example, if you were to convert the above JSX code to JavaScript, you’d get the following:

ReactDOM.render(
  React.createElement('a', { href: "https://xkcd.com/221/" },
    React.createElement('img', {
      src: "https://imgs.xkcd.com/comics/random_number.png"
    }),
  ),
  document.getElementById('app')
)

The thing about JSX is that to use it, you’d need a build process, which would mean (at minimum) understanding and installing NPM. And if you’re just getting started, learning a build process to avoid typing React.createElement() a few times doesn’t make any sense. Luckily, you don’t need JSX!

Instead of having JSX convert tags into React.createElement() calls, you can call React.createElement() directly. While you’ll end up typing a few more characters, it makes React’s workings clearer and allows you to avoid build systems entirely.

To see this in action, try copying the above code block into the editor below. And remember – you’ll get more benefit from typing it out than copying and pasting!

//
// Try out the above code block here!
//

Now that you’ve called createElement() a few times, do you think you have an idea what it does? If not, relax – we’ll cover it soon. But putting this aside for a moment, what does that ReactDOM.render() method do?

What’s a React?

At it’s simplest, React is a library for creating and updating HTML elements.

ReactDOM.render() is the function that actually does the creating and updating. It takes a React Element object that describes what to render, and uses this to update the DOM node that’s passed in as the second argument.

But wait a moment, isn’t React.createElement() creating elements? It is, but maybe not in the way you’d expect. The “elements” that createElement returns are actually plain old JavaScript objects that describe the element that you’d like ReactDOM.render() to create. It might help to think of React Elements as configuration objects for ReactDOM.render().

Let’s play with Elements

The best way to come to grips with React elements is by toying around with them, and that’s what this editor is for. Here are a few thing to try:

  1. Comment out ReactDOM.render() – notice how nothing is displayed, even though React.createElement() is still being called
  2. Add more square arguments to the container’s React.createElement() – notice how you can use a single element more than once
  3. If you’re feeling adventurous, try defining another element with a different color and rendering it as a child of container
const square = React.createElement('div', {
  style: {
    width: '100px',
    height: '100px',
    backgroundColor: 'red',
    margin: '10px',
  }
})

const container = React.createElement(
  // The first argument specifies the element's type
  'div',

  // The second argument specifies the element's attributes, or "props"
  { style: { border: '5px solid blue' } },

  // The remaining arguments list the element's children
  square,
  square,
)

ReactDOM.render(container, document.getElementById('app'))

Elements are just Objects

React Elements are just JavaScript Objects. Each object contains enough information to describe a single node in the DOM. They also contain some magic smoke that React uses to keep track of the elements, but you’ll never need to touch this unless you want to work on React itself.

There are three properties of a React Element that are worth caring about:

  • type specifies what type of HTML element to use; it also lets you specify custom types, which we’ll get to later
  • props specify the attributes on the element, as you may have guessed from the style prop above
  • children lets you specify the element’s content; it can contain a string, another React Element, or an array (containing strings or React Elements)

The React.createElement() function requires that you pass a type and props as the first two arguments. Any further arguments are treated as the element’s children.

Prop Naming

One thing that can be a little tricky is remembering which properties you can set on the props object. While these are mostly the same as standard HTML attributes, you’ll sometimes find a few differences. For example:

  • Instead of class, you must use the className prop to set CSS classes
  • Instead of a for attribute on your <label> elements, you must use a htmlFor prop
  • Instead of passing a string for style, you must use an object with camelCased names

If you know the DOM, then this probably feels familiar. If not, remembering the differences directly can be a bit of a pain. But there’s a trick – take the name of the HTML or CSS attribute that you want, and camelCase it.

Here’s an example:

const style = { display: 'none' }

React.createElement('div', { className: 'field', style: style },
  React.createElement('label', { htmlFor: 'name' }, 'Name')
  React.createElement('input', { id: 'name' })
)

Of course, no mnemonic is perfect. So to make life easier, you can print out the hi-res prop-naming cheatsheet that you’ll get when you register for free as a React Armory member – but I digress! Now that we know what elements are, let’s practice using them.

Join React Armory,
Get Cool Stuff

Exclusive access to resources.

Early access to new content.

No spam, ever.

It’s just JavaScript

Since React.createElement() is just JavaScript, you can use it amongst loops, if statements, and anything else JavaScript allows.

Here are a few examples:

// Create a different greeting element depending on the time of day
let greeting
if (new Date().getHours() < 12) {
  const style = { color: 'green' }
  greeting = React.createElement('h1', { style }, "Good morning!")
}
else {
  const style = { color: 'red' }
  greeting = React.createElement('h1', { style }, "Good afternoon!")
}

// Create an element, but only if it is the weekend
const dayOfWeek = new Date().getDay()
let weekend = null
if (dayOfWeek === 0 || dayOfWeek === 6) {
  weekend = React.createElement('strong', {}, "Hooray! It's the weekend!")
}

// ReactDOM.render() expects a single element, so if you want to render
// multiple elements, wrap them in an empty `div`
const root = React.createElement('div', {},
  greeting,

  // If a child is `null`, `false` or `undefined`, React is smart enough
  // to not render anything
  weekend,
)

ReactDOM.render(
  root,
  document.getElementById('app')
)

React Spiral FizzBuzz

Now that you’re familiar with React Elements, let’s use them to play React Spiral FizzBuzz!

If you aren’t yet familiar with React Spiral FizzBuzz, the rules are as follows:

  • You must draw 15 boxes in a spiral, numbered from 1 to 15
  • If the number is divisible by 3, the box should display “Fizz” in strong type
  • If the number is divisible by 5, the box should display “Buzz” in strong type
  • If the number is divisible by both 3 and 5, the box should display “FizzBuzz” - again in strong type
  • Otherwise, the box should just display the number in normal type
Housekeeping

Some examples import helper packages with the ES6 import statement. If you’d like to dive into the imported code, you can view it on React Armory’s GitHub Page.

Figuring out how to position the boxes in a spiral is a bit of a pain, so I’ve supplied a getBoxStyle(n) function that returns a style object for box n.

To start you off I’ve supplied an array with 3 box elements. Now obviously, you could “win” by just repeating the existing createElement() line 15 times and manually setting the content. But instead of doing this, try to use a loop to create your boxes array.

One last thing: make sure you pass a unique key prop to each box, just like the starting code. We’ll discuss why you’d want to do this a little later.

If you’re having any trouble figuring it out, you may press the “Show Answer” button. But please, don’t push the button unless you’ve given it a bloody good crack.

import { getBoxStyle } from 'react-armory-spiral'

const boxes = [
  React.createElement('div', { style: getBoxStyle(0), key: '0' }, '1'),
  React.createElement('div', { style: getBoxStyle(1), key: '1' }, '2'),
  React.createElement('div', { style: getBoxStyle(2), key: '2' },
    React.createElement('strong', {}, 'Fizz')
  ) ,
]

ReactDOM.render(
  React.createElement('div', {}, boxes),
  document.getElementById('app')
)
import { getBoxStyle } from 'react-armory-spiral'

const boxes = []
for (let i = 1; i <= 15; i++) {
  let content = ''
  if (i % 3 === 0) content += 'Fizz'
  if (i % 5 === 0) content += 'Buzz'
  if (content === '') content = String(i)
  else content = React.createElement('strong', {}, content)
  boxes.push(
    React.createElement('div', { style: getBoxStyle(i - 1), key: i }, content),
  )
}

ReactDOM.render(
  React.createElement('div', {}, boxes),
  document.getElementById('app')
)

Got it? In that case, Congratulations! If you can write FizzBuzz in React then you’re well on your way to creating Todo lists or getting a well paid job at a mega corporation!

What’s in a fractal tree?

But back to the problem at hand – we’re building an animated tree. And since we now have a single branch of the tree, it looks like we’re a good part of the way there! There’s just one problem…

Fractal Tree

The thing about the swaying tree from the first example is that each square has two child squares; one on the left, and one on the right. This means that there is no way to give you a simple getBoxStyle(n) function – the nth box could have parents on the left and the right.

In order to calculate the style for a box in a tree, we’ll need to know whether it is on the left or the right of its parent. Or in other words, we’ll need to know about the box’s environment.

Now sure, we could do this by creating some funky recursive JavaScript. But as it turns out, React gives us a much simpler way to create elements based on their environment…

Continue to: Custom React Elements

Join React Armory,
Get Cool Stuff

Exclusive access to resources.

Early access to new content.

No spam, ever.

React Armory is growing. Join in to be the first to experience new lessons, examples and resources.