Getting started with React: The Fundamentals

This blog is a part of the series ‘Getting started with React’.

In part 1, we will be covering the core concepts of React.js and gradually building on that knowledge as we progress over the course of other Parts which I will publish following this.

In this Part, we will be creating a simple Superhero application, which can be used to list Superhero profiles and play with Superhero profiles.

*A note for those who are a bit familiar with React.js already: Please note that we will be creating this application in the conventional way using class based and functional components, both, and will be covering the newer React Hooks in a separate part. Using these hooks we will create purely functional applications.

Getting started with the project setup

Ensure that your system has create-react-app cli tool installed. We will be using this to generate our project instead of manually configuring it entirely.

In your preferred directory where you want your project to be generated, run the following command:

This command will create the base project structure, with the project named as ‘my-superheroes’, and your project directory should look as follows:

This initial structure, thanks to the abstracted configurations by create-react-app, comes with a basic server which will make your react application available in your browser for development.

In the terminal, after going into the directory (hint: at the level where package.json file is present), run the following command:

You must have yarn pre configured for this command to work. We are using yarn mainly because of how quicker it is compared to npm. Yarn performs a lot of operations in parallel, and caches dependencies which are already installed, among other such advantages which you can google for.

After running this command, you will have an instance of your react application running on your local machine.

And, on visiting the path specified in your browser:

This is the basic app which comes bundled with create-react-app.

Before we begin, let us first discuss how exactly this initial structure works to render the default React application in your browser.

In your project directory, open the index.html file which is present at the path public/index.html:

We know that React.js is used to serve SPAs (Singe Page Applications), and this is the single file which will be served by your actual application in the end, when it is deployed. Hence, it is placed in the public folder like this, and named index.html as is the convention.

On opening index.html, you will find the most important part in the html:

This is the root element where our react application will be “attached” to the actual HTML. This will become clearer in a while. Just remember we had a “root” element in our index.html file.

Next, we will open our index.js file, which lies on the path src/index.js in your project directory. This is where we will start seeing React in play.

Its contents look something like this:

Do not be baffled by the many imports in this file, we are just concerned with the “App” import and the ReactDOM import for now. Note that as we haven’t covered components yet, just imagine <App /> to be like an HTML element where it will eventually be replaced by some HTML content which the App import holds.

Now how does React.js connect to the actual DOM in the browser, which will be rendered in the end? We are in the end going to serve the index.html file, right, which is supposed to be a plain HTML file?

This is done with the help of ReactDOM as we saw above, which provides many methods which can be used at the top level of your react application. One such method in action is already in front of you:

Remember the “root” element we saw in index.html? ReactDOM.render() uses a reference to that element: document.getElementById(‘root’) , and hooks our <App> component into it.

This is how we establish our React application’s link with the outside world, into the single index.html page which will eventually be served to the client.

By doing this, we control the contents of said page, using React’s diffing algorithms for efficient DOM updates (hence, “ReactDOM” should sound like a pretty apt method name now). This will be explained further at the end of this blog, when we have more understanding of how components work.

We will now move on to understand our default <App> component better.

The App component

Open your App.js file, which you can find on the path src/App.js within your project directory. This file is where our default component is defined, which we passed to the ReactDOM.render() method.

If you are using a newer version of create-react-app, your App.js component may look like this:

This is a “functional” component, to encourage usage of react hooks and discourage usage of class based components.

However, we will cover Hooks later and hence will need to transform this into a class based component for now, since we will focus on the conventional way of development for a React application.
This is because most of the existing projects have been developed using this approach, and Hooks still haven’t become mainstream yet everywhere. Most of the recruiters out there will be expecting you to be familiar with the conventional way, at least in my immediate surroundings. And anyway, we will still look at react hooks later in a separate part so you get to learn both! We will also understand the differences between class based components and functional components as we proceed.

For now, first of all we will need to import the { Component } class definition from ‘react’ package.

Change the top import in your App.js file to:

After this, we will be converting the function into a class as follows, but by also extending Component:

The changes are basically as follows:

The Component class needs to be extended so that an ordinary javacript class becomes a React component class. Think of a component as a special HTML container which has the capability to change the contents dynamically, and maintain local state, at different points in time: creation/mounting, updation and unmounting.

This gives the class access to a local state, and various lifecycle methods which can be used at different stages of a component’s lifecycle within the DOM: mounting/creation of a component, its updation and its unmounting. The state is used to keep track of the current “state” of critical data in the component, at different points in time.

If you look at the code for App.js, we are already using the render() lifecycle method.

This is the only required lifecycle method whenever creating a React class based component. This is because, it is this method which returns that weird looking HTML,

which is eventually rendered to the DOM. This, in fact, is not HTML at all. It is something called JSX.

JSX is basically syntactic sugar, which can be used to easily create the HTML view for our React component along with many other advantages.

But why do I call it syntactic sugar? Because say, to create a simple HTML div as follows, JSX will actually translate the code behind the scenes. This means, something like:

will be eventually translated to something like this:

Please note something major here- this line in App.js at the top of the file:

We imported React even though we never used it explicitly anywhere. JSX is the reason for this import, it requires the React.createElement() method behind the scenes, as we showed above!!!

Using JSX allows us to skip writing the complicated syntax for rendering HTML elements, and we will see more advantages of JSX as we progress further. I will help you take note of them wherever I can.

For now, let us start playing with our component!

Using State

We will start by defining our first hero profile, this will be a static profile. I believe Geralt of Rivia, from the Witcher series will be a good fit to begin with, also because I love playing the game so much!

But where do we define the model for our first hero? We will define it in the component’s local state. First of all, let us remove the contents of our App.js file. It should end up looking like this, so we have a clean slate to begin with:

The differences are as follows:

We will now add state to our component. To define state, we can do the following:

We will now see another advantage of using JSX. To display the hero name and power, we will use the following:

Using the curly braces as shown above, we can inject simple javascript expressions and variables into our JSX, and hence, eventually into our DOM!

Save the changes and view your web app in the browser. It should look something like this:

Congratulations, you have just rendered your first Hero! But wait. How is the text centered? We did not write any css yet, after all. Let us understand this first before we move to updating state.

Styling your component:

In your App.js file, have a look at the main div and its attributes:

Now, have a look at the App.css file, in the same directory (src/App.css):

In javascript and hence, JSX, class is a reserved keyname. This is why, we use className instead to define our CSS classes on an element.

Now, an interesting thing. Look at how we are importing our CSS into our App.js file:

We can also import our styles as an object as well, and access CSS as properties of this object. In newer versions of the create-react-app development environment, we have something called “CSS modules”, implemented by default by the build tools.

All you have to do is rename your component’s CSS file to *.module.css, in this case: App.module.css:

And now, to import the CSS as an object, we change the previous import from App.css to now be:

Thanks to the abstraction by create-react-app, our development environment gives us a default export from our CSS module which can be imported as shown above.

Now, changing our className attribute in the main div:

Thanks to JSX, we use curly braces to extract the required CSS class for styling, from the classes object we imported before.

But why was this approach needed? Inspect your web page, and look for the div with this CSS class. You will find the class attribute looking something like this:

That weird code appended to our class name, is done thanks to using CSS modules like we just did.

This is used to make the name of the class scoped locally to only the component it is imported in, to uniquely identify a class for a component. This prevents any class names from clashing in our project, for eg. a common class name like .btn or .button may be present in multiple components’ CSS styles. We would not want the styles of one to override the styles of the other component.

This means, you could have another component, with a CSS class with the same name (.App), and still have different styles defined and applied to both the components. Since both components have their own unique “code” for identifying this class.

We will now try to add some new styling to the App component. First of all, get rid of everything in your App.module.css file except the .App class.

It should look something like this:

Great! Now let us try to give our hero a kind of card layout effect.

In you App.js file, enclose the hero details with the following div:

And add the following class in App.module.css:

Your page should now be looking something like this:

To verify, the changes in the files were as follows:

Iterating over a collection of heroes

We now have a few of the basics cleared, so let us begin to add more heroes! Let us first choose the new heroes we will add. They will all be from random games off the top of my head, which I’ve loved to play in the past:

2B from Nier: Automata
Aloy from Horizon Zero Dawn
Emily Caldwin from Dishonored 2
Artyom from Metro 2033
Dohvakiin from Skyrim

Let us add them to the heroes array in src/App.js:

But wait. After adding all those heroes, do we have to manually create hero div blocks for each hero again? That would be so tedious to do!

I mean, the same kind of div after div after div…. :

There has to be a better way, right? Well since JSX is not HTML, we have access to javascript inside it! Therefore, this makes it easy to create iterables which we can use to generate these blocks for every hero.

Change your JSX, from looking like this:

To now look like this. Well, just the contents of the render() method:

I wrote the JSX code and stored it in a constant here just to show you the flexibility of using JSX. This is how I prefer to show any dynamic JSX, by storing it in its own constant (or variable, using ‘let’, if it is subject to change conditionally).

Let us add a title to our page as well, a heading to show that this page shows superhero data. We will use a simple <h1> tag for this:

Go ahead, add it.

It will crash our application. If your IDE with its extensions is smart enough, it will already display the reason to you.

All JSX expressions described as above, must be enclosed within a parent element. Or they should be an array of JSX elements, which is the case with the heroesDiv const in our code:

The other workaround to this is, using React fragments. Let us add it to our code:

The empty tag which encloses our parent-less JSX here: <> </>, is a React Fragment. View the application in your browser again and it should be running perfectly.

That <h1> tag seems off-putting though, aligned to the left like that. Let’s fix this. This is a good time to show you how to use inline styling for your JSX elements. In the render method of your App component, where we return the JSX, add the following “style” as shown:

It is a special attribute which accepts a configuration object, with camelCased CSS properties and their values. Know more about it here.

Your page should end up looking something like this (I have zoomed out to fit all the contents) :

You can verify the differences in code for what we covered until this section here:

Creating a new component

So far, we have only worked with the default App component provided to us by react. We will now see, how we can create our own component.

But first, let us set a goal which we will achieve using this component. Let us create a component which will allow us to change the power of our superhero, and reflect the changes dynamically.

First of all, we will create a folder called ‘components’, in our project’s src directory. This folder will contain all of the components which do not maintain their own state. More on this in a while, after we create our first component.

Create another folder inside src/components, called InputHandler, with a single InputHandler.js file inside it:

Here’s a surprise for you, this will not just be the first component we create on our own, but also the first functional component we create!

Let’s start by giving it a basic skeleton:

As you can see, a functional component unsurprisingly, is just a function which returns some JSX.

In your App.js file, import this component from src/components/InputHandler/InputHandler, and add it to each Hero card. Add this to your App.js file imports:

And change your heroesDiv constant, holding the JSX for out Hero card, to look like this:

Any component which is imported, can be used as shown here. You just have to make it its own tag, taking care that the tag name matches the name of your import. Do note the text casing conventions everywhere in this blog.

Save the changes, and see how your page looks like in the browser. If everything went right, it should look like this:

Let us adjust the styles a bit again, in your InputHandler component directory (src/components/InputHandler), add an InputHandler.module.css file:

In this CSS file, add the following styles:

And add a div around your input element, with the className as shown:

Your page should now be looking a bit neater. Again this is zoomed out to fit all the contents:

And obviously nothing happens if you type into the input element right now. We haven’t configured any functionality to it.

Let us change this, to add the functionality to change a hero’s powers dynamically by typing into the input component for that hero.

But how do we go on achieving this? A major difference between class based components and functional components is, that class based component have access to a local state. We used this state to reflect our heroes, in the App.js file:

Then accessed it to create our JSX:

It would be ideal to have any methods which change this state directly, to be present in the component which holds this state itself.

This is what is encouraged in react development, to have as little “stateful” components as possible, i.e. component which define a local state. Also, only such components which define a state, should be accessing the state directly and manipulating it. They should merely be distributing the state down to other “stateless” components.

All methods which will directly access the state, will ideally reside only in the stateful component!

By keeping the state as consolidated as possible, we avoid direct changes to it by multiple components and reduce the scope of error and inconsistency in state values by not having a state defined everywhere.

Let us create a method which does this for our case, a method which accesses a certain hero and changes his power in the state. To uniquely identify our heroes, let us give each an arbitrary “id” property. In your src/App.js file:

Now we will create a method to change the hero’s power based on the hero id. Add it right below the state in App.js:

The setState( ) method is a special method provided to change the internal state of a component. Whatever you pass as argument will be merged into the previous state. If a new property is passed as argument, it will be added to the state object instance, and if an old property is passed then it will be overwritten.

Cool, so we have a function which expects the changes power and the index of the hero object in our heroes array defined in the state. This much should be clear.

How then, do we make changes to this state through our functional component, InputHandler?

Props

We will pass a reference to this method using what we call “props”. This is a special object injected by React into a component, to be used to pass data from a parent component into a child component. In our case we can simply do this as follows:

It may look weird, coming from our HTML background, to see such arbitrary “attributes” being defined on a tag. But these arbitrary “attributes” are basically properties on the props object, which will be made available inside the InputHandler component as follows by react:

In your browser, you will now be able to change the powers for each hero dynamically:

Let us see what exactly did we do here.

  • We created our method which will access and make changes to the state’s heroes array, in App.js
  • We then passed a reference to this method, to our InputHandler component, using an anonymous method so that it doesn’t get executed immediately after the elements are rendered.
    It should only be executed when the onChange event in our input element is actually triggered. This event will eventually be passed to the method reference, when the onChange event occurs in InputHandler’s input tag:

and the InputHandler component’s input element:

We have basically set up two way binding here, where the value inside the input element comes from the App.js heroes array’s state, and where onChange triggers changes in the heroes array again using the method reference available via props.

Note again, that the state is accessed directly only in the component which has created the state. It is only distributed otherwise.

Let us also add functionality to remove a hero from this list. In App.js, assign an ID to each hero, so that we can identify them during the delete operation:

Create a method which will remove that hero from our array, and update our heroes in the state:

Again, changing our heroesDiv constant in App.js, to have the click event fire our removeHeroHandler whenever we click on the hero’s name:

We will also use this opportunity to remove this error you must have seen in your console:

This error arises whenever in an iterable, the enclosing element does not have a “key” prop. React uses this “key” prop to keep track of iterables for efficient updates, this is explained better here if you want to have a look.

Add a key prop to the enclosing div as follows:

This will get rid of the “key” props error we were seeing earlier.

How React updates the DOM: An overview

Now that we have a (hopefully) better understanding of how components work, let us have a look at how react updates the DOM.

The ReactDOM.render() method initialises the page eventually with our <App> component and all of the “HTML” that is contained within it by painting the entire DOM, but for every subsequent update within the component it will use React’s diffing algorithms for optimised updates. This is why this method is required, so that the HTML we render becomes a part of the React.js environment.

React’s approach to updating the DOM can have an entire blog in itself, however we will look at it from a high level.

Basically, React.js maintains the DOM in the form of its own javascript representation. This is because accessing the actual DOM again and again, is an expensive operation.

This javascript representation is called a Virtual DOM (VDOM). Now, React tracks two such representations: an Old VDOM and a new VDOM.

The older VDOM is the DOM representation created by React before any component updated as the result of some event (or for now, assume simply any “HTML” updated), and the newer VDOM is the future representation after a component updates. Note that this newer VDOM is not rendered to the actual DOM yet, think of it as a prediction of what things will look like in the DOM, in the future.

React.js compares both of these representations, and finds differences in their DOM tree. Only, and only if it does find any differences, React will update only those differences in the real DOM while keeping everything else intact. For example, if only the text within a button changed, only that text will be re rendered to the real DOM instead of the entire button. We avoid accessing the real DOM as much as possible this way!

However, if no differences are found, React will not update the real DOM at all.

Let us understand this with the application we have created so far. In your browser, inspect your webpage and look for the “Rendering” devtools option:

Now enable the following setting inside the Rendering dev options:

This option highlights the areas of the DOM, which needed to be repainted after any changes were made to the page. Try editing Geralt’s power and see what happens:

As expected, React makes the updates only where they were required, optimising them as much as it possibly can using its diffing algorithms.

Well, I guess that is it for this part. It will become too overwhelming, if it isn’t already, to put more stuff in here. For now, try creating a similar application for your favourite type of entities. We used heroes here, maybe try using celebrities, Harry Potter characters, Football Players etc. to create a similar list which can be edited.

Building things, breaking things, learning things

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store