Learning to Work With React Components

Note: This post is work-in-progress learning-note and still in active development and updated regularly.

In previous learning posts, Setting Up React Development Environment and Learning ReactJs – A Basic Overview were discussed. In the React review post, we covered only basic overview of React with some terminology like React virtual DOM, elements, Using JSX, components and props & state.

ReactJs is very popular JavaScript (JS) library and most developers like to learn/use this popular technology in their projects. As a result, there numerous books, tutorials, blog posts written on React app. Because in React world everything is component, understanding of React components is crucial to begin making use of this powerful tool to design and create customized react application.

The purpose this learning-post is to learn how to work with a simple react component using static HTML set up and Create React App module.

Project Overview

The main objective of this project was to build a simple blog site header app (shown below) using with both (i) Create React App (a npm package) and (ii) Adding Scripts Tags to HTML files.

Static HTML File with Scripts

An HTML file of the site header component was prepared using HTML markup and styled as follows. Because our objective here to learn to build an react app, HTML markup & CSS styling will not be discussed here.

Step 1: Mock up & HTML Markup

The following figure shows outline of our site header HTML mark up. The site header image shown below is used as background to site-header element.

Fig: Site header app mock up & HTML mark up
Step 2: Start with blank HTML page.

Started with a blank HTML file as shown below with updated title tag with React Blog.

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>React Blog</title>
  
</head>

<body>
   
 <script>
<!-- react app codes-->
</script> 
  
</body>
</html>
Step 3: Add Scripts tags

To create an React App core React library and React DOM components essential, without them react app can’t be build. The following scripts were added just below the title tag in the header section.

//load scripts from CDN
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
//add css style sheet 
<link type="text/css" rel="stylesheet" href="site-header-style.css">

The first two <script> load React. The third <script> loads Babel JavaScript compiler library which is essential to interpret JSX files into simple JS files.

Step 4: Add CSS style sheet to header

CSS styles rules can be added with <style> tag above <body> tag. To avoid cluttering all the styles are saved in site-header-style.css file, added with <link> tag below the <script> tag in header (line 6).

Step 4: Add a DOM container to HTML

A unique container inside <body> tag is needed to display the content of the react app. This is the entry point for React to our HTML page. So following empty <div> tag with a unique id=main HTML attribute is added.

<!-- DOM container with an unique id  -->
<div id="main"></div>

The unique DOM container id is linked in our JS file and display react component inside it.

Tip: Quoting from React guideYou can place a “container” <div> like this anywhere inside the <body> tag. You may have as many independent DOM containers on one page as you need. They are usually empty — React will replace any existing content inside DOM containers”.

Step 5: Creating Site Header React Component

Next step is to create our site header components. The component code reside inside the <script> tag before the closing <body> tag. To avoid our HTML file cluttering, the site header component codes are saved in site-header-comp.js file and the component file is loaded inside the <script> tag as shown in line . File structure of site header component is shown below:

#!site-header comp file structure
js/
  site-header-comp.js
image/
  headerimg.jpg
react-site-header.html
site-header-style.css
  • js folder: It contains site-header-comp.js file which is our actual react component.
  • image folder: holds header image headerimg.jpg file
  • react-site-header.html: This is static HTML file
  • site-header-style: CSS rules for site header component.

At this point, putting all together HTML file looks as shown below:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>React Blog</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
  <link type="text/css" rel="stylesheet" href="site-header-style.css">
</head>

<body>
 <!-- DOM container -->
  <div id="main"></div>
  <!--load react component-->
 <script type="text/babel" src="js/site-header-comp.js"></script> 
  
</body>
</html>

The React component codes goes inside the <script></script> tag (line 17). For organizational purposes, in this example JS codes are linked to external JSX file site-header-comp.js inside js folder. It is important that file type should include type="text/babel" attribute or else Babel will not be able to detect JSX and fails to transpile JSX into JS and thus throwing error.

Step 6: Creating Site Header Component

Lets start building SiteHeader component with a basic starter “Hello World” React code:

//starter react code
class SiteHeader extends React.Component {
  render() {
    //instructs React to render code in HTML
    return <h1>Hello World</h1>
  }
}
// instructs to attach App to #main HTML div'root' HTML div
ReactDOM.render(<SiteHeader />, document.getElementById("root"))

Lets modifying the codes inside render() method (line 3) as shown below:

//site-header component
  class SiteHeader extends React.Component {
  }
  ReactDOM.render(
   //instructs React to render code in HTML
    <div>
       <div className="site-header">
           <div className="site-title-text">
	     <h1 className="site-title">React Blog</h1>
	    </div>
	    <div className="main-menu">
	     <ul className="main-nav">
	        <li className="active">Home</li>
	        <li>About</li>
	        <li>Contacts</li>
	     </ul>
            </div> 
       </div>
    </div>,
    // instructs to attach App to #main HTML div 
    document.querySelector("#main")
    );

In the example above, JS ES6 Class is used which inherits from the React.Component class (line 2) as described in React Guide. Next, it contains required render() method (line 3) which instructs the React to render the content within the block main block ( <div> line 6 and </div> line 19). In the example, SiteHeader component is returning HTML content between lines 7-18, using React’s ReactDOM functionality, which were copied and pasted from HTML markup (Step 1 above). Because JSX is optional although most react component use JSX syntax.

Finally, built-in document.querySelectorById is used (line 21) to grab main element (line 21) created in HTML file (step 4).

Step 7: Viewing in Browser

When the updated react-site-header.html file is previewed in a browser, the following is displayed.

Figure: Site header screen shot.

In the above example, we learned how to put together a header image and top navigation menu, as one static component in an HTML file.

Creating Complex Components

In the previous section, we learned how to build a simple static header react components and view with HTML file.One of the advantage of working ReactJs is it allows to combine components to create a more complex components.

In this section we will learn how composing & splitting component into smaller components (eg. site-header into two components: header and navigation). In addition, two components: post-listing and footer will be added to build a blog post page component prototype.

Note: This section was inspired by Creating Complex Components by Kirupa and Thinking in React from ReactJs Guide.

Step 1: Sketch & Identifying Visual Elements

The following sketch shows a real world blog page example to build upon SiteHeader component (yellow) from the previous section. As shown in the figure (below), two additional sections: blog posts, and footer are included in the sketch.

Figure: Blog Post sketch showing component markup
Step 2: Identifying Component Hierarchy

As shown in the above mock up figure, the page is divided into the following five main visual components:

  1. BlogPost (red): a container component which holds all the four main components.
  2. Header (yellow): contains header image (as background) and banner text header.
  3. Nav (orange): contains site navigation.
  4. PostList (green): contains main body of the post with lists of post. Currently it is just static (block of HTML code) page.
  5. Footer (blue): contains footer section of the blog post page.

Note: At this stage, the details under post-list section are ignored. Main objective is to put together several small components into a larger main (one) component.

The above components are arranged into following hierarchical order:

#!component
BlogPost
    Header
        Nav
    PostList
    Footer

As shown in the above example, the BlogPost components holds four smaller components and serves as a container component.

Step 3: HTML File Template

The same HTML temple and file structure used in previous section (step 5) were used to create composite BlogPost component. As shown in the above sketch, the blog post HTML are hard coded and styled as appropriate.

Step 3: Creating BlogPost Component template

For defining components the name used in Step 2 (above) <strong>BlogPost</strong>, <strong>Header</strong>, <strong>Nav</strong>, <strong>BlogList</strong> and Footer are used as component names. A blank component template is shown below:

/* React BlogPost Component */
class Footer extends React.Component {
   render() {
      return (
	  //insert footer section code here
         <div>
            <p>Footer content goes here.</p>
         </div>
      );
   }
}
class BlogList extends React.Component {
   render() {
      return (
	  //insert page content code here
         <div>
	   <p> Site content goes here </p>
        </div>
      );
   }
}
class Nav extends React.Component {
   render() {
      return (
         //insert Navigation section code here
         <div>
	    <p> Site Navigation goes here </p>
         </div>
      );
   }
}
class Header extends React.Component {
   render() {
      return (
	   //insert header section code here
         <div>
           <p> Site header goes here </p>
         </div>
      );
   }
}
class BlogPost extends React.Component {
   render() {
      return (
      //putting all comp in container comp
    <div>
       <Header/>
         <Nav/>
       <BlogList/>
       <Footer/>
    </div>
      );
   }
}
//instruct to attach BlogPost Component to #main HTML div
ReactDOM.render(
    <BlogPost/>,
	document.querySelector("#main")
	);

In the above BlogPost component template, four components starting from the bottom Footer component (lines: 2-11) and working to the top of hierarchy – BlogList (lines: 12-21), Nav (lines: 22-31), Header (lines: 32-41) and BlogPost (lines: 42-51) are defined.

Step 4: Building The Components

It is time to work on individual components. Before starting this project, each component was tested as individually to evaluate it works and has no error. The same Header & Nav components used in the previous section were used in this section too.

The following four components were build by simply cutting & pasting the highlighted codes either from previous components or HTML file.

4.1. The Footer component: The following highlighted snippets (lines: 5-7) were cut from HTML file and pasted in template (step 3) as shown below.

//Footer component
class Footer extends React.Component {
   render() {
      return (
         <div className="site-footer">
            <p>Powered by ReactJS | Content, Layout, Design: TinjureWP 
             | @2018 All Right Reserved.</p>
         </div>
      );
   }
}

4.2. The BlogList Component: This component was previously tested as individual BlogList component. the following highlighted codes (lines: 6-56) were added in as shown below.

//BlogList component
class BlogList extends React.Component {
  render() {
    return (
     <div>
        {/* .post-1 -*/}
	<div id="main" className="site-main" role="main">
	  <header className="entry-header">
	    <h1 className="entry-title">Welcome to React Blog Home </h1>
	  </header>{/* .entry-header */}
	  <div className="entry-meta">
	     <div className="entry-meta">
		Written by : Blake Shelton. Posted on: October 20, 2018. 
                File under: uncategorized.</div>
	      </div>
           //adding figure
	    <figure classname="full-bleed">
	       <img src="image/home-img.jpg" alt="Beautiful mountain" width="auto" 
                height={700} />
		<figcaption classname="figcaption">Fig: Beautiful Mountain. 
                 Photo credit: Unplash</figcaption>
	    </figure>
           <div className="entry-content">
	       <p>Welcome to WordPress. This is your first post.
                Edit or delete it, then start writing!</p>
	   </div>{/* entry-content  */}

	   {/* .post-2 */}
	   <header className="entry-header">
		<h1 className="entry-title">This is Second Post Title </h1>
	   </header>{/* .entry-header */}
	   <div className="entry-meta">
	    <div className="entry-meta">
		Written by : Adam Levine. Posted on: October 20, 2018. 
                File under: uncategorized.</div>
	    </div>
	    <div className="entry-content">
	        <p>Welcome to WordPress. This is your first post. 
                 Edit or delete it, then start writing!</p>
	     </div>{/* entry-content  */}

	     {/* .post-3  */}
	     <header className="entry-header">
		<h1 className="entry-title">This is Third Post Title </h1>
	      </header>{/* .entry-header */}
              <div className="entry-meta">
		<div className="entry-meta">
		Written by : Kelly Clarkson. Posted on: October 20, 2018. 
                File under: uncategorized.</div>
                </div>
	     <div className="entry-content">
	         <p>Welcome to WordPress. This is your first post. 
                 Edit or delete it, then start writing!</p>
	     </div>{/* entry-content  */}

      </div>{/*.site-main  */}
    </div>
    );
   }
}

The highlighted codes shown above is simple HTML with JSX required comments (eg. {/* comments goes here */} ).

4.3. The Nav Component: The highlighted snippets (lines: 6-12) were copied from the previous SiteHeader component and pasted as shown below.

//Nav component
class Nav extends React.Component {
   render() {
      return (
      //menu section
        <div className="main-menu">
	    <ul className="main-nav">
		<li className="active">Home</li>
		<li>About</li>
		<li>Contacts</li>
	   </ul>
        </div>
      );
   }
}

4.4. The Header Component: The highlighted snippets (lines: 6-10) was cut from the SiteHeader component from the previous section pasted as shown below.

//Header component
class Header extends React.Component {
   render() {
      return (
        //header 
         <div className="site-header">
            <div className="site-title-text">
		<h1 className="site-title">React Blog</h1>
		</div>
         </div>
      );
   }
}

4.5. The BlogPost Component & Putting Together: Its a container component. What this component does is to call all the four components, Header, Nav, BlogPost & Footer in the same hierarchical order. This way only BlogPost component is pass to ReactDOM.render() function to display all the components.

//BlogPost component
class BlogPost extends React.Component {
   render() {
      return (
      //putting all comp in container BlogPost comp
    <div>
       <Header/>
         <Nav/>
       <BlogList/>
       <Footer/>
    </div>
      );
   }
}

When a component is called its render() function returns some bulb of HTML. To quote from Kirupa “Each component’s render function returns some HTML to another component’s render function. All of this HTML keeps accumulating until a giant blob of HTML is pushed (very efficiently) to our DOM. That simplicity is why component re-use and composability works so well. Each blob of HTML works independently from other blobs of HTML – especially if you specify inline styles as React recommends. This allows you to easily create visual elements from other visual elements without having to worry about anything.”

Step 5: Putting All Together

Finally, lets pass BlogPost component to ReactDOM.render() function to display all the components in HTML document as described in React Guide and shown below.

//instruct to attach BlogPost Component to #main HTML div
ReactDOM.render(
    <BlogPost/>,
	document.querySelector("#main")
     );

When index.html is viewed in a browser, the the BlogPost component is rendered to the DOM (please use following View link to view the rendered page).

View Demo

Next Step

The run time <script> tag based approach used in this example works for small application and for learning process because this is resource taxing and painfully slow. Next step is to build this same project in react development environment with create-react-app npm package.

Wrapping Up

In this learning-note post, basic structure of a react component and building a simple react component using run time <script> in a HTML file were discussed. An example of combining small components into creating a more complex components was demonstrated.

NEXT: Learning to Create App Components with Create React App

Useful Resources and Links

While preparing this post, I have referred the following references extensively. Please to refer original posts for more detailed information.