1. Learn
  2. Learn React By Itself

Custom React Elements

React frees you from the binds of HTML by letting you create custom elements. And the best part? All it takes is a simple function.

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

In part one, you learned how to create React Elements using types like 'div' and 'strong'. But React isn’t limited to elements from HTML – it also allows you to create custom types. And in the React parlance, these custom types are called Components.

Components are types

Actually, you’ve already seen a React Component in action; the PythagorasTree element from the first example is a Component that I created just for this guide.

When you first encountered a PythagorasTree element it was created with JSX. So let’s convert it back into plain JavaScript and take another look:

main.js
PythagorasTree.js
index.html
Build In Progress

Creating a React Element with a Component is just like creating a HTML element. The only difference is that HTML elements are represented by strings, while custom elements are represented by Component objects. Everything else stays the same. React.createElement() still returns a React Element object, and the type on the returned object will still be the type you passed in.

But what happens when you render a Component element? The browser doesn’t understand custom components, so it doesn’t know what to do. Instead, you’ll need to tell the browser how to render your custom element in terms it understands. And to do so, you’ll use a Component Function.

Component functions

Component functions are also called Stateless Functional Components within the React community.

In React, Components are just functions. These functions accept the props of an element, and return the HTML that should be rendered in their place as a React Element.

This is easier seen than explained, so let’s look at an example:

main.js
index.html
Build In Progress

Custom props

Custom elements are like HTML elements in that they can receive a list of props. But unlike HTML elements, a component can be passed whatever props you’d like – whether they be strings, numbers functions, or even other elements!

Actually, Components are not limited to returning HTML Elements. They can also return Elements with custom types. They can even return an Element that was passed in via props!

For example, you could create a component that expects to receive an Element on its children prop, and then use that Element as part of its return value:

main.js
index.html
Build In Progress

The children prop

In fact, when you pass a child element to React.createElement(), React will automatically add a children entry to the element’s props. This means that you can rewrite the above example without specifying any props for your Center element.

Try testing this out in the above editor. Once you’ve given it a shot, or if you get stuck, you can check your solution below.

function Center(props) {
  const style = { textAlign: 'center' }
  return React.createElement('div', { style }, props.children)
}

ReactDOM.render(
  React.createElement(Center, {},
    React.createElement('h1', {}, "Cream puffs and kimchi!")
  ),
  document.getElementById('app')
)

Tree components

At the risk of repeating myself a little too much, component functions can return any element. They can even return an element whose whose type is itself. Like this:

function Tree(props) {
  return React.createElement(Tree, {})
}

Of course, the above component will break React – it’d create an infinitely deep Tree component that doesn’t do anything. But by passing through a prop to limiting the tree’s depth, you can create all manner of useful trees – family trees, directory trees, or in our case, fractal trees!

And armed with your new knowledge of components, you should now be able to put together the fractal tree that you saw earlier!

Let’s draw a fractal

I’ve started you off with a broken TreeBox component. This component draws a single styled div, and also draws a single child – but only if its level prop is lower than the global totalLevels variable.

To complete the tree, you’ll need to make two changes:

  1. Pass a level prop to the component’s children that increases until it hits totalLevels
  2. Render a second child on the left, in addition to the child on the right.

If you have any trouble, you can take a look at the solution. But make sure you give it a decent crack first!

main.js
PythagorasTree.js
index.html
Build In Progress

Congratulations on getting this far! You’ve now created a fairly complex component, and have a solid understanding of React’s fundamentals. There’s just one problem…

Reusable components

While the Tree component from the previous section works, it isn’t very reusable. What if you ever want to have two trees with different heights, sizes or depths?

Sure, a fractal tree component probably never needs to reused anyway. But you never know!

The problem with my above TreeBox component is that it depends on global state. The heightFactor, lean, size and totalLevels variables will be the same across all elements. If we were to pass this information as props instead, it could be reused multiple times with different settings. For example:

main.js
PythagorasTree.js
index.html
Build In Progress

Object.assign(target, obj1, obj2, ...) assigns the properties from obj1, obj2, etc. to target. You can use it to copy one set of props onto another.

Read more at MDN.

If you are still new to React, you may not yet see much of a problem with relying on globals. Passing props can feel a little verbose, and may seem like unnecessary effort. But even if the use of props adds a few lines to your components in the short term, it’ll seriously improve your apps maintainability and readability on the long term.

The thing about props is that they allow each of your components to be completely self contained and reusable. And that’s why this is my first rule of React:

The First Rule Of React

If it is practical to pass the data you need through props, it must be passed through props.

As it turns out, most of the difficult parts of writing a React application stem from situations where it isn’t practical to pass data through props. There are a number of ways of dealing these, each of which we’ll get to in time.

But I’m getting ahead of myself. We’re building an animated tree, and it still doesn’t look very animated. So let’s bring it to life.

Continue to: Rendering and Re-rendering

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.