Introduction
This post starts a new series in this blog talking about a famous Javascript Framework named React JS. React is a reactive framework which aims for better responsiveness of the application where parts of your system "listen" to each other and at any change they react to it by doing some action like re-rendering or fetching data from a backend server, etc. This is an evolution of the Observable Pattern.
To better focus on React in these posts I will not talk about NodeJS and Webpack but if you want/need to learn these two things please refer to these previous posts I made:
All of them teaches with practice and working codes, what you have to do to have a functioning basic Node/Webpack application with SASS. But if you already have knowledge on all of these and only want to focus on learning React, clone my bitbucket repo and checkout webpack_frontend
branch:
git clone https://bitbucket.org/kiberStender/node_app.git
cd node_app/
git checkout --track origin/webpack_frontend
This branch has all the code developed throughout the three posts above. Everything said let's dive in and learn about React.
React JS
What does exactly React JS do that deserves your attention? I'm going to show you two pieces of code and I want you try to figure out which one executes faster:
let arr = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; let ul = document.querySelector("#a_ul"); // an unordered list <ul id="a_ul"><ul/> for (const item of arr) { ul.innerHTML += `<li>${item}</li>`; }
let arr = [ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, 21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60, 61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80, 81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100 ]; let ul = document.querySelector("#a_ul"); // an unordered list <ul id="a_ul"><ul/> ul.innerHTML = arr.reduce((acc, item) => `${acc}<li>${item}</li>`, "")
If you are not well experienced with Javascript you would say that the first one is faster, because it's only 21 items. The thing here is: innerHTML
is not a simple variable. Any changes to this triggers I/O(Input/Output) operations in your browser. I/O is a very expensive operation and not only expensive but unlike changing a variable value, doing I/O can fail due to many possible problems(like too much delay to process due to lack of cpu or memory resources at the time so browser cancel your IO operation) and given the decision of making it a variable instead of a function for example, it is not visible by the developer that it can fail and error may arise by lack of attention.
By executing the first code we are triggering 21 I/O operations while in the second piece of code, even though we have a bigger loop (101 items) we only do one I/O operation.
And what does React has to do with it?
React works with the idea of controlling the number of I/O operations you do by not allowing you to do it yourself. But how can React know when to perform I/O and when not? React performs comparison of variables, so whenever a variable changes something React triggers re-render operations only on the parts of your code that are affected by that value that changed. To control it, Reacts wants you to not change variables directly:
let a = 10
a = 5 // Do not do this
React has an 'interface' where it has a function/method named setState
and by using this function, you control rendering or let React knows when a variable has changed and then triggers re-render operation(more on this later). By doing so, React always knows when and how many I/O to be performed, because it controls what it calls Components and any Component inside the Component that triggered setState
will be updated too.
Instead of doing one I/O per Component it does what the function reduce
does to the array, processing everything in one single batch and then returns a single object to React to do the I/O.
Adding React to our codebase
Now, before I go any further in explanation, let's re-write our simple "Hello World". The first thing we have to do is to add React in our dependency list. React is a framework like Bootstrap, so we're adding it to normal dependency list not the dev-dependency list:
npm install react@16.13.1 react-dom@16.13.1
PS: To guarantee that everything will work in the future as it is working right now, please install all the dependencies in the same version I put here in the snippet
React itself is inside react
library, for now don't focus on react-dom
as we will only use it in the application's start. Now go to your /src/javascript/greetings/DateGreetings.js
file and change it to the given example:
import React from "react"; // 1
import moment from "moment";
import "greetings/dateTimeGreetings.scss";
export default (props/*3*/) => React.createElement( // 2
'div', {id:"date-time-greetings-component"}, `It is: ${moment().format(props.dateFormat)}` // 4
);
Let's go to the explanation:
- The first thing to be done is import React to your code
- Then make DateTimeGreetings class to become a function
- I will explain props later but, essencially it is an object with external values that whoever is using your Component pass to instante it
- Notice that now it is using
props.dateFormat
instead ofdateFormat
because now, dateFormat is passed via props not via constructor
React.createElement
In what is called vanilla Javascript there is a function named document.createElement
which only receive one parameter, a string containing the name of the TAG you want to create and returns and instance of DOM Node. With this Node instance you can "populate" it with attributes like id, css class(es), etc:
const div = document.createElement("div");
div.setAttribute("id", "my-div");
div.classList.add("my-css-class");
div.classList.add("my-css-class-2");
And then you can programatically control your page adding or removing Nodes or Node attributes when some button is clicked or some input data is given. But, as you may take notice, I had to write 4 lines to describe one single div
that has actually 2 attributes(id and class). React thought about that and created their own createElement
function were one can do this in a shorter way:
const div = React.createElement("div", {id:"my-div", className:["my-css-class", "my-css-class-2"]});
Not only it is shorter but easier to understando too. And this is the whole base of React, all the fuss you eard about is because of this piece of function. With this you can create programatically create your whole page deciding when something will be rendered and when not.
JSX
Wait a minute... What is this strange syntax? This is probably not what you have seen so far when people talk about React. You probably have seen React like this:
import React from "react";
import moment from "moment";
import "greetings/dateTimeGreetings.scss";
export default (props) => (
<div id="date-time-greetings-component">
It is: {moment().format(this.props.dateFormat)}
</div>
)
So how to achieve this? This HTML syntax in the middle of the Javascript is called JSX. It is a transpiled language in the middle of the transpiled Javascript that is transformed in this 'weird' syntax seen above. To have this syntax in your code making it easier to write and read, you have to simply add another preset in our Babel configuration (in babel.config.js
file). First install babel react preset:
npm install --save-dev @babel/preset-react@7.9.4
Now go to /babel.config.js
and add the newly installed preset to our config:
module.exports = {
presets: [
[
"@babel/preset-env",
{
targets: {
node: "current",
},
},
],
"@babel/preset-react",
],
};
PS: Whenever you see three dots ...
, it means: "keep whatever comes before this". Or if it comes after what we are adding/modifying, it means: "keep whatever comes after these dots"
Now "reactify" /src/javascript/greetings/Greetings
:
import React from "react"; // 1
import DateTimeGreetings from "greetings/DateTimeGreetings.js"; // 2
import Person from "person/Person";
import "greetings/greetings.scss";
export default class Greetings extends React.Component { // 3
render(){ // 4
const {name, surname} = this.props.person ? this.props.person : new Person("Unnamed", "Person"); // 5
return React.createElement(
"div",
{id: "greetings-component"},
`Hello Mr/Ms ${name} ${surname}`,
React.createElement(DateTimeGreetings, {dateFormat: "MMMM Do YYYY, h:mm:ss a"}) // 6
);
}
}
Allow me to explain:
- Again import react
- Import our class newly transformed to Component DateTimeGreetings
- Make Greetings a Component too
- Change
greet
name torender
- Greetings now receive person parameter via props(Calm down I will explain what props are) instead of via direct
this
as it was done previously - Instantiate DateTimeGreetings as if it was one of the React's pre-defined HTML tags and pass
dateFormat
via props to the instance of the class
Update /src/javascript/App.js
:
import React from "react";
import Person from "person/Person";
import Greetings from "greetings/Greetings";
import "app.scss";
export default class App extends React.Component{
render(){
const person = new Person("John", "Titor");
return React.createElement(
"div",
{id: "greetings-example"},
React.createElement("h1", null, "Greetings Example"),
React.createElement(Greetings, {person: person})
);
}
}
I don't think there is much to be explained here that was not explained in the previous examples. At last, go to /src/index.js
file and change it to this:
import React from "react"; //1
import ReactDOM from "react-dom"; //2
import App from "App";
ReactDOM.render( // 3
React.createElement(App, null), // 4
document.querySelector("#root") // 5
);
Explaning:
- Like previously, import React to our code
- Now import ReactDOM. This is the 'engine' of React. This is what makes React works the way it works. If you know Java, think about the class Thread. Just by creating an instance of this class won't make it work. You need to call
start
method and you will need to specify anExecutor
(usuallyGlobalExecutor
) and then your Thread "will be executed"(If there are resources for it). If you are not Java dev or not familiarized with Thread class, React Dom is what starts your React app and control the lifecycle - Here is where the command to React-DOM start the application to run is given
- Creating an element of type App, like it was done with Greetings and DateTimeGreetings previously in other components
- Here we say where we want our react app to be rendered. If for some reason you want to have a second app you can simply call
ReactDOM.render
again passing a differentdocument.querySelector("another_element")
And voi là. To guarantee to you that it is working and it is not a cache, I changed "Node Dev" to "John Titor". So check it, if you see the different name, you can be sure you did everything correctly. Run now using npm run-script live
and go to http://localhost:8080

Check out the generated pure HTML code:

And now you have React JS in your project. As you can see, React is not a framerwork to beautify your app, like for example, when you are learning JQuery. Even though you can use JQuery without adding CSS dynamically, it is counter intuitive. React is made for you to focus in the structure of you HTML and how to dinamically change values diminishing the maximum possible I/O operations. If you compare it to jQuery that does I/O almost all the time, React is mostly to improve performance while keeping your code (more) readable.
JSX
Wait a minute... What is this strange syntax? This is probably not what you have seen so far when people talk about React. You probably have seen React like this:
import React from "react";
import moment from "moment";
import "greetings/dateTimeGreetings.scss";
export default class DateTimeGreetings extends React.Component {
render(){
return (
<div id="date-time-greetings-component">
It is: {moment().format(this.props.dateFormat)}
</div>
)
}
}
So how to achieve this? This HTML syntax in the middle of the Javascript is called JSX. It is a transpiled language in the middle of the transpiled Javascript that is transformed in this 'weird' syntax seen above. To have this syntax in your code making it easier to write and read, you have to simply add another preset in our Babel configuration (in babel.config.js
file). First install babel react preset:
npm install --save-dev @babel/preset-react@7.9.4
Now go to /babel.config.js
and add the newly installed preset to our config:
module.exports = {
presets: [
[
"@babel/preset-env",
{
targets: {
node: "current",
},
},
],
"@babel/preset-react",
],
};
PS: Whenever you see three dots ...
, it means: "keep whatever comes before this". Or if it comes after what we are adding/modifying, it means: "keep whatever comes after these dots"
Now You can start writing JSX HTML inside your Javascript files and Babel will transpile it correctly.
/src/javascript/greetings/DateTimeGreetings.js
... render(){ return <div id="date-time-greetings-component">It is: {moment().format(this.props.dateFormat)}</div> } ...
/src/javascript/greetings/Greetings.js
... render(){ const {name, surname} = this.props.person ? this.props.person : new Person("Unnamed", "Person"); return ( <div id="greetings-component"> Hello Mr/Ms {name} {surname} <DateTimeGreetings dateFormat="MMMM Do YYYY, h:mm:ss a" /> </div> ); } ...
/src/javascript/App.js
:... render(){ const person = new Person("John", "Titor"); return ( <div id="greetings-example"> <h1>Greetings Example</h1> <Greetings person={person} /> </div> ); } ...
/src/index.js
... ReactDOM.render(<App />, document.querySelector("#root"));
React.createElement and JSX
Understanding how JSX is transformed to React.createElement
can helps us understanding some informations we will see with more details in the next topics. First let's see createElement
prototype:
React.createElement(
type,
[props],
[...children]
)
type
: A string or object containing the component we are instantiating. For any native HTML Tag, you pass it as a String like 'div', 'span', 'article', etc. For your own defined Components such as our Greetings, you pass it not as a String but as a 'anonymous class definition' or a type if you preferprops
: It's an object literal{}
containing the values you want to pass to your instantiated Component. In the prototype it is surrounded by [] not to say it is an array, but to say that this is optionalchildren
: It is a varargs array that you can pass anything you want, as long as it is serializable to a String. Usually customized Components do not have children. It's not a rule, it is just that usually you don't nest things inside your own Component from outside the file defining it. In the prototype it is surrounded by [] not to say it is just an array, but to say that this is optional too
Non JSX version:
React.createElement(
'div',
{prop1:"string", prop2:a_variable},
"child1", "child2", React.createElement('span', {id:"abc"}, 'text')
)
React.createElement(
Greetings,
{person: new Person("Javascript", "Dev")},
"child1", "child2", React.createElement(AComponent, {id:"abc"})
)
Now JSX representation:
<div prop1="string" prop2={a_variable}>
child1
child2
<span id="abc">text</span>
</div>
<Greetings person={new Person("Javascript", "Dev")}>
child1
child2
<AComponent id="abc"/>
</Greetings>
React Components
I mentioned a lot previously(here and here) that React has something named Component. But what is a Component? A Component can be two things:
- A function that returns a JSX/React.createElement:
or//1 function Greeter(props){ return <div id="greeter-component">{props.greet} {props.treatment} {props.name}</div> } //or //2 function Greeter(props){ return React.createElement('div', {id:"greeter-component"}, `${props.greet} ${props.treatment} ${props.name}`); }
//3 const Greeter = (props) => <div id="greeter-component">{props.greet} {props.treatment} {props.name}</div> //or //4 const Greeter = (props) => React.createElement('div', {id:"greeter-component"}, `${props.greet} ${props.treatment} ${props.name}`);
- A class that extends
React.Component
orReact.PureComponent
and has a methodrender
that returns the JSX/React.createElement
PS: If you are not doing anything than callingclass Greeter extends React.Component { constructor(props){ super(props) } render() { return <div>{this.props.greet} {this.props.treatment} {this.props.name}</div> } } //or class Greeter extends React.Component { constructor(props){ super(props) } render() { return React.createElement('div', {id:"greeter-component"}, `${this.props.greet} ${this.props.treatment} ${this.props.name}`); } }
super
in your constructor, it is optional to have it:class Greeter extends React.Component { render() { return <div>{this.props.greet} {this.props.treatment} {this.props.name}</div> } } //or class Greeter extends React.Component { render() { return React.createElement('div', {id:"greeter-component"}, `${this.props.greet} ${this.props.treatment} ${this.props.name}`); } }
PS: Because of the interpreted nature of Javascript, you cannot jump lines after return
otherwise the interpreter will return undefined
. So if your JSX expression it too big you wrap parenthesis around it and you can jump as many lines as you want/need.
...
export default class SimpleMenu extends React.Component {
render(){
return (
<div id="orkut-menu">
<ul>
<li>Home</li>
<li>Friends</li>
<li>Scraps</li>
</ul>
</div>
)
}
}
All of this to tell you that a Component is just you creating your own HTML Tag. By doing this, every Component you create is a part of your application, making it easier to compose these parts in the end, like it is just a big HTML file. If you run, you will notice that again nothing changed in the final result, but check the generated HTML:

Component as a Function vs as a Class
The advantage of having a Component as a function is that, it is less verbose and faster to be coded, see examples 1, 2, 3 and 4(specially 3 and 4). Usually you will use this way when you have a simple Component, such as our Greeter, that only displays something and has no interaction with the user like when you are creating a Header, Footer or any static part of your app that will not change by the Component own inner actions.
On the other hand having a Component as a class, will grant you way more control over your Component, because by then you will have support from React lifecycle and state changing using this.setState. You lose in amount of written code, but you gain in level of tunning or optimization of your Component.
But in any case, to change from a class to a function or vice-versa is not that hard, so if you're not sure what is the better approach to use, go for class approach, if you see that your Component is only changed by outside(via props
), or you don't need to tune/lifecycle, you can easily change it to function approach later.
What are these "props"?
Props is short for "Properties". Think of your Component as a function, the props
are your parameters, but instead of passing your parameters by position like you normally do in a function, here you are giving names to your parameters so you can pass them in any position.
Once you pass a props
in your JSX or React.createElement you will have access to it inside your class/function that declares your Component using props.[the very same name]
you declared outside your class/function when instantiating it. You can pass literally anything via props
: functions, strings, int, double, complex objects, anything that Javascript allows you to put inside an object, because if you remember how we pass props
in createElement
function, it is just an object literal. See the example:
Declaring

Instantiating

Notice that props.greet
in the first picture is being populated in the second picture via greet="Hello"
. If you forget to populate it like that, your props.greet
will be undefined
in your class/function. So always remember to either protect your props
with some if else or to always populate your props correctly when instantianting your Component. See a simple example on how to protect your Component against undefined
variables:
...
const Greeter = (props) => <div id="greeter-component">{props.greet ? props.greet : "Hello"} {props.treatment} {props.name}</div>
...
This way whoever is using your Greeter Component and forget to populate greet
, the Component will assume it's value as "Hello".
How does it work internally?
Now that you understand that the core of the React is the React.createElement
and everything revolves around it(even JSX that it is just a syntax sugar for this function), I created a simple code that actually does what React does. Of course it is very limited as it does not have State support, Lifecycles support, good perfomance, Virtual DOM, etc, etc. It is just a simple didactic example to better explain each part of what have been shown so far:
function createElement(type, props, ...children){
return addChildren(createNode(type, props), children);
}
PS: You can check the whole code here
Notice that create element does 3(three) things:
- Create the HTML TAG:
React uses a class named Element created by React dev team that is later translated using the Virtual DOM. Don't take my code as a closer implementation to the original from React as in the original one Render is not the first function to be called in the lifecycle.function createNode(type, props){ if(typeof type === "string"){ return addProps(document.createElement(type), props); } else { if(type.prototype instanceof Component){ return new type(props).render(); } else { throw new Error("Classes must extend Component"); } } }
- Add the props:
The props here, as you can see, are the properties an HTML TAG can have. So if you know what properties an original HTML TAG it will be the same as passing them in pure HTML code. React is nothing more than you creating your own TAGs while composing original HTML and third parties TAGs created by other developers. And when you are creating your own TAG(a.k.a your own Component) you are free to give whatever name you want to your props. You will have access to them viafunction addProps(element, props){ for(const [key, value] of Object.entries(props)){ switch(key){ case "onclick"://Any other listener like ondbclick, onchange, onhover, etc element.addEventListener("click", value); break; default: element.setAttribute(key, value); break; } } return element; }
this.props.theNameYouGaveWhenDeclaringYourTag
. - Add children to the TAGs:
This is complete optional as usually when you create your own TAG/Component, you don't need to have children because, you cannot control these children outside your TAG/Component. They will be handled by whoever is declaring your TAG/Component and in the perspective of your TAG/Component no child will be visible. Think about it as you declaring afunction addChildren(element, children){ for(const child of children){ if(typeof child === "object"){ element.appendChild(child); } else { element.append(child); } } return element; }
div
TAG with aul
inside it. The only thing the TAGdiv
can actually see and control is its props because, in the perspective of thediv
it does not matter if it has child at all it is just a matter of structure.
So the state is ... ?
While props
are external values provided to your Component via parent Component, they are fully immutable and changing them inside your Component won't trigger any re-rendering. So how can we mutate values to interact with our users? As mentioned in the beginning, React has a function named setState to deal with mutations that will only be available if your Component is a class extending React.Component
or React.PureComponent
. You have to create a variable named state
(and pay attention to not give any other name, it has to be state
) and this variable should be an object holding, if possible, only values (like String, Int, Double, Complex classes representing a value like Date) or anything that can be comparable:
...
constructor(props){
super(props)
this.state = {
greet: "",
treatment: "",
title: "",
aNumber: 0
}
}
...
And in order to change one of those values you have to use setState
like that:
...
myFunctionThatChangesGreet(newGreet){
this.setState({greet: newGreet})
}
...
Or:
...
myFunctionThatIncrements(value){
this.setState(state => ({aNumber: state.aNumber + value}))
}
...
Or:
...
myFunctionThatChangesGreetAndIncrementsANumber(newGreet, aNumberToIncrement){
this.setState(state => ({aNumber: state.aNumber + aNumberToIncrement, greet: newGreet}))
}
...
Independently of what you choose to use (simple object passing or anonymous function passing) this command will trigger React to compare old greet
with newGreet
and aNumber
to the new value to check if there are differences. If there are differeces, React re-renders your Component and any child inside it. Pay attention to this part React re-renders your Component and any child inside it
. So if you don't break your application in as smaller Components as you can, you might have performance issues because it will have too many things to re-render everytime you change a single variable.
Changing treatment
All of these examples of how to change values inside this.state
are awesome but, how actually to do this in real world? Let's add a input
to allow the user to type what "treatment field" they want to be displayed instead of "Mr/Ms". Inputs in React are simple Components that demands you to bind/attach/implement the listener onChange
and optionally bind/attach a variable to the props value
. Bind/Attach are the terms used to describe when you are passing a variable to some prop in an given Component, in this case an input
. This onChange
is a listener and it is just a function with the signature:
onChange(event: Event): void
Let's modify our src/javascript/greetings/Greetings.js
a bit so you can have an example:
...
constructor(props){
super(props);
this.state = {
treatment: ""
}
}
whenTreatmentChanges(newValue){
this.setState({treatment: newValue})
}
render(){
return (
<div id="greetings-component" className="a-class-that-changes-font-to-red">
<div className="row">
<div className="col-1">Treatment</div>
<div className="col-2">
<input value={this.state.treatment} onChange={event => this.whenTreatmentChanges(event.target.value)} />
</div>
</div>
<Greeter greet="Hello" treatment={this.state.treatment} name={this.props.name} />
</div>
)
}
...

setState callback
setState
function is asynchronous, so if you change something outside another statement right after it in the next line expecting it to have the new values already it won't work. So if you need to fire something exactly when setState
finishes updating your state
variable, you can pass an anonymous function as a second parameter to setState
:
...
whenTreatmentChanges(newValue){
this.setState({treatment: newValue})
console.log(this.state.treatment) // print old treatment value
}
...
This will show you the old value because as explained, setState
is asynchronous, so in order to correctly do something after setState
finishes updating you'll need to do the following way:
...
whenTreatmentChanges(newValue){
this.setState({treatment: newValue}, () => console.log(this.state.treatment)) // print updated treatment value
}
...
Testing Components
Conclusion
We are going to stop it right here, because this is becoming too huge. So to not lose details, I'm leaving the more complex side of React to the next post . You learned in this post (I hope ^^) how to add React to your project, how to have JSX and what are the diffences when not using it, what props are, what Components are and how many types of Components we can have and how to deal with state.
We did almost no code here, we had more explanations than examples, but it was enough for you to have a good start with React. From this point on, you will be able to code an application in React even if you don't read next post(please do it xD). If by any chance you would like to read this in portuguese, feel free to go to the Brazilian Portuguese version of this page. See you next time.