What are Components?

Lets hear what the creators of React have to say about components.

Components let you split the UI into independent, reusable pieces, and think about each piece in isolation.

Well that doesn’t provide much information! 😕

They really meant that:

React components are the core building blocks of a React application that represent how a particular element would be visualized on the User Interface.

Combining tens to thousands of components together makes up your application.

A component must be designed in a way that makes it reusable across any page or even projects.

A component may be responsible for performing a single task (if any).

A button or an input component for example has a single responsibility of allowing the user to perform an action or type input via their keyboard or keypad respectively.

React provides us with HTML elements as components out-of-the-box, they work and behave the same way as we expect them to work in HTML.

Simple enough right? Not exactly! The description feels like its a piece of cake but I have seen experienced developers scratching their heads especially when it comes down to identifying and styling components.

Identifying Components 🔎

The best way to identify components is to have a design in mind or prepare a sketch for the application. This way you have an idea about what components are actually going to be implemented before-hand rather than deciding what to include at runtime. Planning/Analysis is the key phase of any development lifecycle that needs to be performed before moving to code the solution.

Stack overflow mobile view

Lets look at every developer’s favorite website, Stack Overflow. If you look closely at the design, you will notice a lot of UI pieces that are being reused across multiple places while others are just used once.

In React’s terminology these UI pieces are known as Components. By looking at the components we can clearly identify some but not all which include buttons (sign up, login), navigation links (questions, jobs, tags, etc), tags (python, gitlab, font-awesome, etc) and much much more. Identifying them will aid us during the development phase.

These components give you an idea about their individual presentation as well as the hierarchy of the page, and as stated, having a look at the design before moving forward is a really important step.

Styling Components 💅

Even though, this is a complete topic in its self, I am going to throw away some pointers that you try to keep in mind when styling a component.

A component should only hold styles that will visualize its appearance on screen or on any state changes (pseudo-selectors and component state), it is not responsible for its layout and position within the application.

Button component

The container component (a component that holds other components) on the other hand is responsible for laying out, spacing, animating, positioning and altering of some styles based on its requirement.

Button group component

How do we Create Components? 💻

React provides us with two ways to create components:

ES6 Class Functions

Both the techniques are responsible for returning a React element. These elements can then be used across various pages to define how the UI will be displayed to the end user.

Class Component

Class components as its name suggests are created using the ES6 class syntax. The following snippet displays two ways of creating a component using the ES6 class syntax (follow which every you like, there is no benefit of using one syntax over the other).

React component created using ES6 class syntax

React component created using ES6 class syntax and named import statement

The code is simple to understand. Every class that extends the React.Component class is obligated to implement the render() method which returns a React element. This element is then applicable to be displayed on the User Interface.

Class components are also known as Stateful components.

Example time

Lets start by creating a simple button component such as the cool one shown above (just not with styles since that a complex topic to dive into and I don’t want your attention to drift away from components). The code for creating the uncool-unstyled-button is as:

A button component implemented using ES6 class

See how simple it is to create a component. All you have to do now is use this component anywhere in your project and there you go, it renders on the user interface as you wanted it to.

Function Component

If the name wasn’t enough, a function component is created using a JavaScript function (anonymous, named, arrow). The following snippets displays three ways of creating a function component (again there are no perks of using one over the other).

Function component using an anonymouse function

Function component using a named function

Function component using an arrow function

A simple difference when compared with class components is that you don’t need the React.Component class to work with function components. The React element returned by the function is visualized on the User Interface.

Function components are also referred as Stateless components.

Yet another example

To contrast between both the approaches we are going to implement the same dry button component as we did with class components.

A button component implemented using an arrow function

You may be amazed (😲) by considering how little effort that actually required. Well, function components are leaner and cleaner that is why most developers prefer to use function components until unless class components are deemed necessary.

Note: The naming convention for function component follows camel casing ( buttonComponent ) where as class component follow pascal casing ( ButtonComponent ).

Class vs Function Component 🆚

The React team gave us two different ways of creating a React component. If you believe that both are the same, then I’d hate to disappoint you by stating class components have features that aren’t supported by function components.

Lets have a look shall we.

State

A couple of paragraphs ago I stated that class components are also called stateful components, and the name comes from the fact that these components posses a state at a particular time. A state can be thought of as an internal representation of the component, the state may also be responsible for changing the styles of the component at any given state. You can think of a light bulb as a component that has the on/off state. When the bulb is on, it glows, else it doesn’t.

A bulb with an on/off state

The state can be represented as an instance variable of the underlying component class (previously you would use a constructor to define an instance variable, this restriction was lifted when Class Field Declaration proposal reached Stage 3, you can still use a constructor but almost every developer uses the class field declaration approach).

Declaring state inside the constructor of the class component

Declaring state using the class field declaration syntax on the class component

Notice the use of the this keyword when using the constructor to define the state. It is required to reference the instance variable of the underlying class instance.

State Example

This example will be a very basic one that will show you how to consume a state. Later on in this blog we will see how it differs from props and in which scenarios can one opt to use state.

Consuming state in a class component

This simple Greeting component will display Hello Danyal with the highest priority heading ( h1 ).

Events

There are 3 syntax for writing down events in a class component, but I will only be covering 2 of them since the 3rd one isn’t optimized (again there is no benefit to which one you use).

An event handler using the arrow function syntax

Notice that the event is defined on the React element. The element’s onClick event has a reference to the incrementCounter method. The onClick event when triggered executes the referred method. The incrementCounter when triggered/executed will update the value of the counter by adding 1 to it via the setState method (we will take a look at setState later in this blog, just note that it updates the state object).

A bidden event handler

The second one is a bit cumbersome to work with since it requires more lines of code. Notice here that the incrementCounter method is now a regular JavaScript function, that means the this reference will depend on how the method will be invoked. To control that the this keyword always refers to the class instance, we bind the method to the this keyword, and as you can see, we have accomplished this in the constructor .

Note: You don’t need to bind the this keyword when using an arrow function since arrow functions already solve that issue for us.

Events in React vs Events in Vanilla JavaScript

If you have worked on vanilla JavaScript then there is a subtle difference that I’d like to point out before moving on:

You don’t need to add event listeners to the DOM via addEventListener method, everything is taken care behind the scenes by React.

method, everything is taken care behind the scenes by React. All event handlers are prefixed with on followed by the event name in camel casing onClick, onChange, onFocus .

. The JSX takes a function instead of a string <div onClick={this.functionName}> vs <div click=”functionName()”> .

vs . You are required to use the event.preventDefault() method to prevent default behavior triggered by the event instead of returning a false value. Example: On a form submission.

Lifecycle Methods

If you pondered over the fact that class components are extended by React.Component , then you already understand that there’s more to this than meets the eye. The render() method isn’t the only method that is provided by React.Component , but there are other methods as well (which I won’t be stating since this topic will get its own blog post) that have different purposes, and those methods are known as Lifecycle methods.

Lifecycle methods are executed behind the scenes when a component is created, updated or deleted. We can override those methods to execute some side effects such as invoking an API call, manipulating the DOM, subscribing/unsubscribing to an event and much more.

I just wanted to give you an idea that such methods exists, but only inside a class component.

Others

The following are other comparisons that you may want to know before moving forward.

Build Size: Function components contribute a less build size.

Function components contribute a less build size. Readability, Testability and Maintainability: Function components are concise and hence easy to read, test and maintain.

Function components are concise and hence easy to read, test and maintain. Lines of Code: Function components take up less lines of code to write down the same component when compared to with an ES6 class.

Which syntax shall I use to create components?

The best practice is to always use a function component except for the following situations:

If the component has some state.

If you want to override the component’s lifecycle method.

If you want to handle an event for the underlying component.

If you are unsure about your situation, then the best practice is to start with a function component and then gradually change it to a class component as your requirements become clearer.

Handling Dynamic Data in Components

I stated that a component needs to reusable. Not only should it be imported and used across various files, but it must also support dynamic content. This means that the component behaves approximately the same with change in data. Imagine just a simple example of a single profile card component that can be used to visualize a profile for millions of user’s and their avatar.

But where and how do we define data for a component? There are actually two ways to accomplish this:

Props

State

Props

If you have read my blog on All about JSX, you would probably know by now how this works, but as a refresher I am going to re-state how to achieve this (no puns intended 😅).

Props are passed down a component via attributes assigned to React elements. Each attribute constitutes as a key-value pair for the props object.

The syntax to pass down props to a function component is as:

Passing down props in a function component

Notice that I’ve said that a component implemented using function component approach follows camel casing, but since we are creating an instance of the component via JSX, it is mandatory that the name of the custom component to start with a capital letter.

Meanwhile its almost similar to pass down and consume props for a class component, the syntax is as:

Passing down props in a class component

Notice that the props are passed to the constructor and the parent constructor call ( super ), this is mandatory if you are actually going to use props and override the constructor method, otherwise this step can be skipped.

The real catch in both the examples is the greeting statement <Greeting name="Danyal" /> . This statement is passing down props to the component with the key name and the value Danyal . The props object therefore would look something like this:

props = {

name: 'Danyal'

}

Default Value for Props

Default props are a way to specify the default value of a particular or all properties that are passed down by the component. If a property hasn’t been passed down and has a value set by the defaultProps property then the default value for that property is used. This can be accomplish by assigning a value to the defaultProps property. Default props needs to be defined after the component definition has been declared.

To set a default value for a function component property, just assign a value to the defaultProps property after the component declaration.

Assigning a default value to the name prop in a function component

Unlike function component, class component has two ways, the first one being exactly the same as the function component approach.

Assigning a default value to the name prop in a class component

The other approach is to use the static keyword and assign a value to defaultProps that follows the class field declaration syntax.

Assigning a default value to the name prop in a class component using static keyword

State

State on contrary is a private property which is fully controlled by the component. Think of state as a piece of data that is always associated and tracked by the component, A clock component for example will have the state that holds the current time and timezone information.

We have already seen how state works in the example provided in the Class vs Function Component section.

The setState method on the other hand was overlooked at that time. This method is provided by React to update the state object. The argument of the setState method takes in an object which can hold either a single or all the state properties depending on which ever state you want to update. We already saw how to update the state in the counter example so lets move forward.

Props vs State

The following are the differences between states and props:

Props are passed to a component while state is a stand alone property of that component.

Both props and state can have default values assigned to them on each component instance creation.

Props are read-only (we forbid you from mutating it) where as state can be changed.

The data stored in state can be passed as props to child components.

Updates to props are synchronous where as state is updated asynchronously.

Rendering Components Dynamically

Another useful feature provided by React is to control when a particular element can be rendered to the User Interface. Once again, this was mentioned back in my All about JSX blog, but lets still look into how we accomplish this.

Dynamically rendering a button on the navigation bar

The code above has a button variable that checks for the user’s logged in status and then holds null or the JSX depending on the outcome. We then refer the button variable as an expression inside the return statement via the curly brackets {button} . This JSX checks if the value of the expression yields true, false, null or undefined, if it does then it wouldn’t render the component to the screen.

Plot Twist: React Hooks

So probably after reading a lot for these past couple of minutes, you may either feel excited to try these features out or are overwhelmed with the knowledge that you just gained. What if I told you things are the same as above? That’s right, with the release of React 16.8 (6th Feb 2019), a new feature called Hooks was introduced by React which changed the landscape about how we think when developing React apps. This feature lets you use React state and other features without ever needing to write a class. This means that you get to use state, lifecycle methods and events (to name a few) inside of a function component as well. Lets start by implementing the increment counter example, but this time using function component and Hooks.

Using state hook inside of a function component

Wow! That’s some lean code right there. IKR!!! 😱

Lets see how it works:

The import statement is importing a useState named import, a helper method which will let us hook function components with state.

named import, a helper method which will let us hook function components with state. The useState method takes in one argument, which is the default value (it could be a primitive of a reference type like states in class components) of the state variable. In this case we are assigning the value 0 to the state variable.

method takes in one argument, which is the default value (it could be a primitive of a reference type like states in class components) of the state variable. In this case we are assigning the value 0 to the state variable. The useState method returns a state variable and the setter method. We can name is according to anything we like using the array destructing syntax [count, setCount] . The variable in our case is the count that has the value set to 0 (our default value), and the setCount is a method that updates its value much like the setState method that we looked at earlier.

method returns a state variable and the setter method. We can name is according to anything we like using the array destructing syntax . The variable in our case is the that has the value set to 0 (our default value), and the is a method that updates its value much like the method that we looked at earlier. The incrementCounter is an arrow function that calls the setCount method supplied to us by state hooks to update the value of the count variable.

is an arrow function that calls the method supplied to us by state hooks to update the value of the variable. The onClick event on the button gets the incrementCounter function reference. When the user clicks the button it executes the referred method, which hence forth increments the value of count by 1.

Phew! I hope that was easy for you to take in, we won’t be looking into other hooks, just the state hook because that was relevant to our current topic. We will have a separate blog on hooks soon because it shows a lot of promise. In the meantime If you want to learn hooks right away then you can jump into Hooks on the official docs.

Paving the way forward

The reason I covered a lot of detail about class components is fairly because Hooks is a new feature and not everyone has gotten used to them, and currently a lot of the developers are learning on how to use them in their actual application therefore its going to take some time before you see hooks in production code. Meanwhile, if you work for an organization and are working on a React project, chances are that you’ll most likely work with classes more than Hooks, and the fact that legacy applications that needs support or change requests will be using class components (since hooks weren’t introduced at that time). So, its fair to say that you are now equipped with traditional and future approaches under your belt.

Form component

This is going to be the final example that will combine most of what you’ve learned in this blog, we will be using the Hooks approach to build the component, after that I’ll point out changes that are required to convert a stateful function component into a class component. Further more, we will take a look at container and controlled components as well.

The design image below depicts the minimal implementation.

Design for a form component

Considering on the design, it may seem obvious that we need 2 components, an input component and a button component and then reuse them 3 and 2 times respectively.

Create-React-App

Lets setup our app using the create-react-app package and then clean it as we did in our first blog.

Make sure that your App.js file look like this:

// App.js

import React from 'react'; import './styles.css'; const app = () => (

<form className="app"></form>

); export default app;

Note that styles.css will act as a global file that will hold styles for all components.

Button Component

Since a button is a reusable component, it needs to handle dynamic data. There are two approaches that can accomplish our goal:

Using attributes: <Button name="Sign up" /> Using content (innerHTML): <Button>Sign up</Button>

I would use the second approach as that’s what we do when we use the <button> element.

Create a Button.js file in the src folder, and code the following:

// Button.js

import React from 'react'; const button = (props) => <button className="button">{props.children}</button>; export default button;

Add the following styles to the styles.css file:

// styles.css

.button {

width: 100%;

padding: 8px 0;

text-transform: uppercase;

border-radius: 2px;

background-image: linear-gradient(to right, #eb3349, #f45c43);

color: white;

font-family: Verdana, Geneva, Tahoma, sans-serif;

outline: none;

border: 1px solid transparent;

font-weight: bold;

transition: all .2s;

} .button:hover {

color: transparent;

border: 1px solid #eb3349;

background-clip: text;

-webkit-background-clip: text;

}

and finally add the following to the App.js file:

// App.js

import React from 'react'; import './styles.css'; import Button from './Button'; const app = () => (

<form>

<Button>Sign up</Button>

<Button>Sign in?</Button>

</form>

); export default app;

Input Component

Similar to the above approach, we are going to create an Input.js file and make them reusable by using props . This component will be responsible for capturing user input.

// Input.js

import React from 'react'; const input = (props) => (

<input

className="input"

id={props.id}

type={props.type}

/>

); export default input;

with the following styles:

// styles.css

.input {

width: 100%;

padding: 10px 30px;

border: none;

outline: none;

box-sizing: border-box;

border-bottom: 2px solid gainsboro;

font-size: 16px;

font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;

}

Even though I showed you a boring component design, should you do just that? A great designer/developer will always try his best to give the best possible solution that he can think of, so lets continue.

Label Component

A label component will be attached to their respective input component via the id prop. So lets implement them.

// Label.js

import React from 'react'; const label = (props) => <label className="label" htmlFor={props.id}>{props.children}</label>; export default label;

Style is with the same fonts as the input since we are going to introduce a little transition effect.

// styles.css

.label {

font-size: 16px;

font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;

}

Icon Component

I am a big fan of font-awesome icons and therefore would be using them in this example. The icons will be displayed inside the input field so that they add more meaning to our user interface.

Before beginning, make sure to add the following cdn import statement to the <head> tag of the index.html file :

Now lets create a Icon.js file:

// Icon.js

import React from 'react'; const icon = (props) => <i className={`icon fa fa-${props.name}`}></i>; export default icon;

Notice that we have used string literal syntax to prefix the name of the class using icon and fa fa- . This lets us just pass the name of the icon instead of retyping icon fa fa- each time. The icon class on the other hand is our class name to style this component.

.icon { font-size: 16px; }

If you import all three components (Input, Label and Icon) in the App.js file, you will notice that the layout isn’t set, and if you recall what I stated about styling components, you will remember that I said that container components are responsible for the positioning and layout stuff, so lets see how we can actually create a container component.

Container Component

The container component by no means is a special component, its just a regular component that nests/holds other components and give them styles that structure them with regards to the user interface.

We are going to name our container as FormControl, this will be responsible for holding the Input, Label and Icon components, as well as passing them properties and styling them.

// FormControl.js

import React from 'react'; import Input from './Input';

import Label from './Label';

import Icon from './Icon'; const formControl = (props) => (

<div className="form-control">

<Input id={props.id} type={props.type} />

<Label id={props.id}>{props.label}</Label>

<Icon name={props.icon} />

<span></span>

</div>

); export default formControl;

The styles are a lot longer since its going to handle pseudo-selectors as well as transitions.

// styles.css

.form-control {

position: relative;

} .form-control > .label {

color: gray;

position: absolute;

top: 8px;

left: 30px;

cursor: text;

transition: all .2s;

} .form-control > .icon {

color: gray;

position: absolute;

top: 10px;

left: 5px;

transition: all .2s;

} .form-control > span {

position: absolute;

bottom: 0;

left: 0;

height: 2px;

width: 100%;

background-color: #f45c43;

transform: scale(0);

transition: all .2s;

} .form-control > .input:focus + .label {

top: -5px;

left: 0px;

font-size: 10px;

text-transform: uppercase;

font-weight: bold;

color: #f45c43;

} .form-control > .input:focus ~ .icon {

top: 8px;

transform: scale(1);

color: #eb3349;

} .form-control > .input:focus ~ span {

transform: scale(1);

}

Finally, we are going to add these container component in our App.js file. Since we coded a dynamic container component, we will be able to add 3 container components at the same time (Email, Password and Confirm Password).

// App.js

import React from 'react'; import './styles.css'; import Button from './Button';

import FormControl from './FormControl'; const app = () => (

<form>

<FormControl

id="email"

type="email"

label="Email"

icon="envelope"

/> <FormControl

id="password"

type="password"

label="Password"

icon="lock"

/> <FormControl

id="confirm-password"

type="password"

label="Confirm Password"

icon="unlock"

/> <Button>Sign up</Button>

<Button>Sign in?</Button>

</form>

); export default app;

Wow that worked better than expected? But note that we haven’t finished our form component yet, there is still an issue when we type a value inside the input field and then blur the input field. Before we resolve this issue, I’d like to take this moment to talk about another topic.

Controlled Components

A controlled component is a component that manages the state of its children. This is useful in places where there is DOM manipulation or when the parent needs to track the value of the children. The parent uses the state to store the value of the child and then pass a callback function and the value to the child so that it can display and allow the value to be updated via the callback.

But why do we want to do this? Its quiet simple actually. We want our data and UI to always stay in sync instead of asking what the value of component X is at a given time, this feature is also be known as Two Way Binding (If you have ever used Angular, this will be relatable). This also means that the component can respond to an action immediately, this includes and is not limited to validation, disabling or enabling a component, or a enforcing a specific pattern for a component to match.

This image below displays a particular use case.