Think about it: what is the most annoying thing about working with JavaScript? All programming languages have loops, conditionals, variables, and logical operations; some have events, but only JavaScript has The DOM. Yes, that is the most annoying part of coding for the web, itโs not only very slow in terms of performance, but also makes your code redundant, cumbersome, and huge.
Just look at this example of all the lines of code we need just to create a simple HTML element into our DOM:
1let divElem = document.getElementById("myFirstDiv"); // Select a parent element 2let myNewHOne = document.createElement("h1"); // Create a new element in the DOM 3let t = document.createTextNode("Hello World"); // Create the content of the new element 4myNewHOne.appendChild(t); // Add the text content to the new element 5divElem.appendChild(myNewHOne); // Add the new element inside the parent element
We can all agree that this is A LOT, right!?
Reactโs main goal is to fix that!
React JS defines itself as a front-end library for building interactive user interfaces (UIs). As such, it proposes a new way of building websites by redesigning the entire coding workflow, as well as making websites faster.
From now on, React JS will take care of the DOM; your job is to create your own <Tags>
and define how they should display (render).
You'll divide your app into small pieces of code (components), and all together they make up the website as a whole.
All of your new <Components>
are individual integral parts of your layout, but some are hidden at the beginning. You will have to show and hide them based on the user's behavior.
So far, we had to concatenate strings to create the HTML we wanted to place in the innerHTML
of any DOM element, for example:
1document.querySelector('body').innerHTML = '<h1>'+person.name+'</h1>';
But React JS comes with JSX
, a special "language" (a syntax extension to JS) that lets you write plain HTML within your React/JavaScript code without having to wrap it in quotes (making it a string). So that eliminates the need for annoying HTML string concatenation.
If you need to use regular JS code within your HTML blocks, you would simply have to wrap the former in curly braces, as seen in the example below, similar to using the construct ${dynamic_code}
that you have seen in our projects before.
1return <h1 id="name"> {person.name} </h1>;
Something to remember is that in JSX/React, dynamic JS code within the HTML code (like above) has to always evaluate as an expression. For that reason, we cannot use JS statements within the curly braces, like an if...else
statement, for example. Instead, we need to use a ternary expression that achieves the same effect.
1return <h1 id="name"> {if(person.name == "John") "John"; else "Tom" } </h1>; // Does not work in JSX 2 3return <h1 id="name"> {person.name == "John" ? "John" : "Tom" } </h1>; // Works in JSX and will evaluate to <h1 id="name"> John </h1> or <h1 id="name"> Tom </h1> depending on the value of person.name
โ๏ธ Familiarize yourself with ternary conditional operations ๐HERE
โ๏ธ Review the differences between expressions and statements ๐HERE
Remember the Bootstrap components?
React takes that concept further by dividing and encapsulating your entire website into smaller components. These components can be based on using the familiar JS structures of function
or class
.
Here is how we declare a React component as a function, which is what we will stick to during this course:
1import React from 'react'; 2 3function MyComponent(){ 4 return ( 5 // Some HTML code should go here 6 ); 7}
Now, let's say that we want this component to return a Bootstrap card every time we call it.
Here is how we do that in a React app.
1import React from 'react'; 2 3// We renamed the component to MyCard 4 5function MyCard(){ 6 return ( 7 <div className="card" style={{width: "18rem"}}> // Notice some HTML attributes change their names or values in order to work in React 8 <img className="card-img-top" src="..." alt="Card image cap" /> // We should now take care to always close self-closing tags 9 <div className="card-body"> 10 <h5 className="card-title">Card title</h5> 11 <p className="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p> 12 <a href="#" className="btn btn-primary">Go somewhere</a> 13 </div> 14 </div> 15 ); 16}
๐ Each component in React needs to have a render method that returns a block of HTML code.
Each component can be rendered by calling its <tag>
which looks just like the HTML tags but always start with a capital letter. The difference is that now the name of the <tag>
is the name of the React component (e.g. <MyCard />
) that you have created, and using the tag gives you access to the look and behavior that you have programmed in your own component.
The above component will now render (display on the page) a Bootstrap card anywhere you call
1<MyCard />
Usually, we call components within the return section of another component:
1import React from 'react'; 2 3function MyComponent(){ 4 return ( 5 <MyCard /> 6 ); 7}
The most simple React component is just a function that returns some HTML. You can also declare any React.Component as a class. The new class that you declare needs to have a render method that specifies how the component should display.
Here is an example of the same <MyCard />
component, but now declared as a class:
1import React from 'react'; 2 3// Here we created the component MyCard as a class 4export class MyCard extends React.Component { 5 render(){ 6 return ( 7 <div className="card" style={{ width: '18rem' }}> 8 <img className="card-img-top" src="..." alt="Card image cap" /> 9 <div className="card-body"> 10 <h5 className="card-title">Card title</h5> 11 <p className="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p> 12 <a href="#" className="btn btn-primary">Go somewhere</a> 13 </div> 14 </div> 15 ); 16 } 17}
โ๏ธ This is a class component. We strongly recommend you to use functional components and hooks instead because class components are legacy.
With React the entire application is considered one component.
The first thing you will do when building big React applications is to define one big component, which we call primary or main. It will hold your entire application.
Then, you need to inject this main component into the website DOM with the method ReactDOM.render(), like so:
1import React from 'react'; // Mandatory import of the react package 2import ReactDOM from 'react-dom'; // Mandatory import of the react-dom package 3 4// Creating our React component 5function MyMainComponent (){ 6 return <div>Hello World</div>; 7} 8 9ReactDOM.render(<MyMainComponent />, document.querySelector('#app')); 10// Implied is that there is a container div with the id 'app' in your original website's HTML body 11// Through <MyMainComponent /> your entire react application will be inserted into that location of the DOM
Because <MyMainComponent />
in this example is the main component, all other components of your application will need to be called inside this main component or in its descendants (children, grandchildren, etc). Any components not being called in the main component or in its descendants will never appear in the DOM and consequently will not be shown on your webpage.
1function GrandchildComponent (){ 2 return "Hello, I'm the Grandchild"; 3} 4 5function ChildComponent (){ 6 return ( 7 <p> 8 <h3>Hello I'm the Child, and below is the Grandchild</h3> 9 <GrandchildComponent /> 10 </p> 11 ); 12} 13 14function RandomComponent (){ 15 return "Hello, I'm just a random component that will not be rendered =("; 16} 17 18function MyMainComponent (){ 19 return <ChildComponent />; 20} 21 22ReactDOM.render(<MyMainComponent />, document.querySelector('#app'));
In this example, <ChildComponent />
and <GrandchildComponent />
will end up in the DOM and will render because they are called within the main component or a descendant. <RandomComponent />
on the other hand, will never be shown on the page because it is not being called in that way.
A "Layout" in React is basically the combination of two or more components into a parent component (referred to as a view).
For example:
Let's say you have a one page website with three sections: Home
, About Us
, and Contact Us
. The "React" way of doing that will be by creating a bigger view component that contains each component (section), like this:
1export class EntireWebsiteLayout extends Component { 2 render() { 3 return ( 4 <div> 5 <Home /> 6 <AboutUs /> 7 <ContactUs /> 8 </div> 9 ); 10 } 11} 12// It is implied that the Home, AboutUs, and ContactUs components have already been defined
โ This is a class component. We strongly recommend you to use functional components and hooks instead because class components are legacy.
Those components that serve to hold the layout of each of your web pages and are not re-used for anything else are what we will call "Views", and the typical components that we can re-use multiple times with different input (like a card or a button component) we will call "Components" in the organization of our application's folders.
This is how React will render your layout:
Each component will have a render method. The final resulting HTML document will be comprised with the merge of all the outputs that all the components have on their render methods. Check out the following illustration to get an idea.
On your application wireframe, you can grab a highlighter and start marking all the components your application is going to have. The easy ones are the typical Bootstrap components: Navbar, Card, etc. You should also define your own components.
In this case, we have decided to create the following components based on the YouTube website:
<VideoPlayer />
: Will render the entire video player with all the <VideoControls />
inside.<Description />
: Will render the video description.<Comments />
: Will display all the comments, and it will have a bunch of <CommentCard />
components inside.<VideoCard />
: Will display a video thumbnail on the left with a small description on the right and will take people to that video page when clicked.<VideoTitle />
: Will render the video title.After you finish identifying your components, it is time to start coding. Create a new JavaScript class in a separate file for each of those components.
Each class needs to have a function called render. This will return the HTML code that the component will output into the website document.
๐ The following demo updates the current time every second:
Any component can have properties (props), just like in HTML. For example, in HTML we could define the src
property of an image like this:
1<img src="http://myurl.com/path/to/image.png" />
In React, we can set properties the same way and our components will be able to read them and display different outputs based on the props that are being passed to them.
1// Here we can invent a new 'textColor' property, but we will have to make sure to code its behavior 2<ClockComponent textColor="red" />
In the code above, we have invented a new property to the ClockComponent example. We will now have to determine and code how that new property will work inside our component. In this particular case, we would have to assign a red color style to the text output of the clock, like this:
Click to open demo in a new window
A real high quality component must communicate with other components only throughout its properties. This way, we will be able to reuse that component a lot of times in the future (similar to the way functions and parameters work).
Every component works like a mini-application. You are able to control and define your component workflow based on a series of available methods that you can declare and code according to your needs.
๐ Here you will find a more detailed explanation of each available life-cycle method.