Creating a Simple Blog Listing React Component

Note: This post is part of creating list component series.This post is work-in-progress learning-note and still in active development and updated regularly.

In JavaScript (JS), iteration of items is a very basic process. A  prior knowledge of ES6 Array.map() method is essential before deep diving into Creating List React component.

In a previous post, Working with Functions and Array.Map() Method in ReactJS, how Array.map() method is used to iterate array items in React were discussed. In another post, Creating List Component in ReactJs, how list of items in array are transform into list of React element was discussed.

Prerequisite
Creating list component ReactJS is advanced topic, it is assumed working JS knowledge on array.map() method, passing props data to react component, and creating list component. These topics are discussed in detail in the JavaScript prerequisite post series.

This post is continuation of previous posts on Creating List React component. In this learning post, essential features for creating Post list component discussed in previous posts will be revisited and refactoring of codes to create a simple functional BlogPost list component will be discussed.

Post List component – An Overview

Blog Post Skeleton

In previous post, Learning to Create App Components with Create React App, creating components for a skeleton of a simple blog post (shown below) are discussed.

Figure: Screenshot of blog post skeleton (from previous post).

The same components markup, code snippets and styles used in this post were used in this post too to create the Header, Nav, BlogPost and Footer components.

Posts List Component

In Creating List Component in ReactJs learning post, step-by-step guide to transform list items in an array into list of React element with Array.map() method are discussed with a simple use case examples as shown below:

Figure: Screenshot showing list of posts array displayed as individual post (from previous post).

The code snippets used in proof of concepts section of the post will be refactored to create BlogList post described in this post.

Goals

In posts referred in the previous sections and other posts, creating Post list components are discussed. The main goals of this learning post is to learn refactoring components into simple and smaller components.

  • Learn to refactor basic react component skeleton syntax
  • Refactor previously described Class and functional components into small simple BlogPost list functional (stateless) components.
  • Build and deploy the App in a remote server

Refactoring Components

React Component Syntax – An Overview

In previous post, basic overview of react components (Class & Functional) and creating both Functional and Class components are discussed.

//function component
const name = 'John';
function App() {
   return (
     <h1> Hello, {name}</h1>
  );
}

//ES6 arrow function
const name = 'John';
const App = () => {
   return (
     <h1> Hello, {name}</h1>
   );
}

// ES6 Classes component
const name= 'John';
class App extends React.Component {
  render() {
    return (
      <h1> Hello, {name}</h1>
  );
}

Revisiting an example (above) from the previous post, a simple App component with a name = 'John' variable is defined to return <h1> element using simple JS function (lines: 3-7) as functional component, ES6 Arrow function (lines: 11-15) and ES6 Class component (lines: 19-24).

Refactoring Component Skeleton Syntax

Skeleton syntax of an App component with Class, ES6 simple Function and ES6 Arrow function is shown below.

A. Class component. A typical ES6 Class syntax of a React Component  called AppName (shown below) includes an import statement (line 2), a class statement (line 4) with class keyword and a required render() method (line 5), used to render in DOM nodes. The return() method contains code blocks as JSX elements and is same in both the functional as well as Class components.

//class component syntax
import React from 'react'
 
class AppName extends React.Component {
  render () {
    return (
      // code from return ()
    );
  }
}
export default AppName;

The above AppName Class component can be refactor (shown below) by including Component in the import statement (line 13) and excluding React from React.Component from Class statement (line 15).

//class component syntax
import React, { Component } from 'react';

class AppName extends Component {
  render () {
    return (
      // code from return ()
    );
  }
}
export default AppName;

The react app is rendered in React DOM render() method using the above AppName class into the root div of an HTML document (shown below).

//rendering AppName
ReactDOM.render(<AppName />, document.getElementById('root'));

B. Functional component. The functional component syntax as same as classic JS function. It includes React import statement but does not use class keyword. The AppName class component from previous section can refactor into a simple functional AppName component as shown below.

//simple function component syntax
import React from 'react'
 
function AppName () {
    return (
      // code from return ()
  );
}
export default AppName;

In the example above, the highlighted code block from return() method (lines: 5-7) is same in both the class and functional components.

C. Arrow Functional component. The AppName simple functional component syntax from the previous section can be refactor into arrow function (line 4) as shown below.

//arrow function component syntax
import React from 'react'
 
const AppName = () => {
    return (
      // code from return ()
  );
}
export default AppName;

Arrow functions are discussed in detail in another post understanding JavaScript arrow function. Use of arrow function in react is discussed in a previous post.

Post List Components with Arrow Function

Step 1: Re-organize SRC Folder Directory

In the previous two posts: Learning to Create App Components with Create React App and Creating List Component in ReactJS, basic App development environment and file structure has been described.

To avoid files cluttering the src/ folder was re-organized as shown below.

<span class="token comment" spellcheck="true">#! App file structure</span>
blog-post/
  build/
  node-modules/
  public/
  src/
    App.css
    App.js
    index.css
    index.js
    image/
       headerimg.jpg
    components/
        Header.js
        Nav.js
        BlogPost.js
        Post.js
        Footer.js
  package.JSON
  package.lock.JSON

Creating container App.js components and App skeleton components (Header.jsNav.js & Footer.js) listed under components/ are discussed in detail in previous post – Learning to Create App Components with Create React App. Creating post list components to iterate array of post items is discussed in Creating List Component in ReactJs and refactored to create Post.js and BlogPost.js.

For creating following listed components, the highlighted snippets from previous posts were cut and pasted into arrow functional component syntax described in previous section.

Step 2: Header Component

For creating Header component, the following highlighted return() block snippets from Header.js component described in previous post was cut and pasted into the Arrow functional component syntax described in previous section.

//Header.js file
import React from "react";

const Header = () => {
   return (
     <div className="site-header">
        <div className="site-title-text">
         <h1 className="site-title">Blog Posts Listing</h1>
        </div>
     </div>
    );
}
   
export default Header;
Step 3: Nav Component

The Nav component was refactored using highlighted return() block codes from Nav.js component described in previous post into arrow functional component syntax described above.

// Nav.js
import React from "react";

const Nav = () => {
  return (        
    <div className="main-menu">
      <ul className="main-nav">
         <li className="active">Home</li>
         <li>About</li>
         <li>Contacts</li>
      </ul>		
     </div>
  );
}
   
export default Nav;
Step 4: Footer Component

Similar to previous section, the Footer component was refactored using highlighted return() block codes from Footer.js component described in previous post into arrow functional component syntax described above.

// Footer.js
import React from "react";

const Footer = () => {
   return (
     <div className="site-footer">
       <p>Powered by ReactJS | Content, Layout, Design: TinjureWP | 
          @2018 All Right Reserved.</p>
     </div>
   );
}
export default Footer;
Step 5: Create Post Component

Creating component to list posts with props is described in detailed in previous Creating List Component in ReactJs post. To create Post.js component, the highlighted return() block code snippet were refactored with arrow functional component syntax as shown below.

//Post.js
import React from "react";

const Post = (props) => {
  return (
    <div className="site-main">
      <header className="entry-header">
        <div className="entry-title">{props.title} </div>		
      </header>{/* .entry-header */}
      <div className="entry-meta">{props.author} </div>
      <div className="entry-content">{props.content} </div>
    </div>
 );
}

export default Post;
Step 6: BlogPost Component

The BlogPost.js component was similarly refactored with the highlighted return() block code snippet into a arrow functional component syntax as shown below.

//BlogPost.js
import React from "react";
// import the Post component
import Post from "./Post";

const BlogPost = (props) => {
  return (
    <div>
      {props.posts.map(post =>
       <Post 
        key={post.id} 
        title={post.title}
        author={post.author}
        content={post.content}/>
        )
       }
    </div> 
  ); 
} 

export default BlogPost;

In BlogPost component above, Post component is called & defined (lines: 10-14). But before its use Post component needs to be imported first (line 4).

Step 7: Finally Putting All Together in App.js File

The App.js is container component. As explain in previous post, all the four components (Header, Nav, BlogPost and Footer) from the components/ folder are imported with import statements (lines: 5-8) and called in the same hierarchial order with highlighted return() code block (lines: 44-55).

//App.js
import React from 'react';
import './App.css';

import Header from "./components/Header";
import Nav from "./components/Nav";
import BlogPost from "./components/BlogPost";
import Footer from "./components/Footer";

const posts = [
 {
  id: 1,
  title:'Hello World',
  author:'Author: Mr Blogger',
  content:'Welcome to learning React!Lorem Ipsum is not simply random text.'
  },
 {
  id: 2,
  title:'Learn React',
  author:'Author: Mr reactJs',
  content:'Start learning ReactJs.Lorem Ipsum is not simply random text. '
  },
 {
  id: 3,
  title:'Learn JavaScript',
  author:'Author: Mr JavaScript',
  content:'Start learning JavaScript.Lorem Ipsum is not simply random text.'
 },
 {
  id: 4,
  title:'Learn Gutenberg',
  author:'Author: Mr Gutenberg',
  content:'Start learning Gutenberg.Lorem Ipsum is not simply random text.'
  },
 {
  id: 5,
  title:'Learn WordPress',
  author:'Author: Mr WordPress',
  content:'Start learning WordPress.Lorem Ipsum is not simply random text.'
  }
];

const App = () => {
   return (
    <div>
      <div>
        <Header />
        <Nav  />
       </div>
       <div>
         <BlogPost posts={posts} />
         <Footer />
       </div>
    </div>
    );
};

export default App;

For displaying posts, it posts array items are defined in BlogPost component (line 51) and hard coded posts array items each with id, title, author and content properties are called (lines: 10-41).

If the App is being build under development environment with hot-loading , after file save it renders expected output with list of posts at localhost:3000 (local environment).

Further Reading: How To Create a React List Component| Andreas Reiterer

Build & Deployment of React App

When a React App is created using <a href="https://www.npmjs.com/package/create-react-app" target="_blank" rel="noopener">create-react-app</a> package, by the App is being build under development environment with hot-loading and rendered to default browser viewing at localhost:3000 (local environment).

1. Build App with npm run build

By default, Create React App creates a build directory with a production build of the App (static version). The build directory (src/build) is created with an assumption that it’s served at the server root and served as site’s index.html.

2. Specify “homepage” Relative Path

For creating an App build for deployment in a website as a sub-folder (eg. https://yoursite.com/your-app) override the default with build an App for a relative path by specifying “homepage” with relative path in package.json file.

In this example, the App is being serve as /react-demo/postlist/ sub-folder, the package.json file was modified by adding homepage with relative path (line 3) as shown below.

{
  "name": "comps-learn",
  "homepage": "http://tinjure.com/react-demo/postlist/",
  "version": "0.1.0",
  ----
  ---
},
3. Copy Build Directory & Upload to Website

With the npm run build command, the Create React App creates a build directory for /react-demo/postlist/. Copy the build folder and rename it with postlist and upload to react-demo folder of the website.

When index.html is viewed in a browser, the static postlist folder contains the static App, is rendered to the DOM (please use following View link below to view the rendered page).

View Demo

Additional Information: Create React App – Deployment

Wrapping Up

In this creating a simple post listing component using static data array were discussed including step-by-step building & deploying the App to a remote Apache server. In the next learning post, I plan to explore basic routing to create pages (About, Contact, etc) components and route them to render different page view.

Acknowledgements: In this learning post, I extensively used examples from Trey A. Davis‘s post Lists and Arrays in React and Andreas Reiterer‘s How To Create a React List Component post.

Next Post: Learning Basic Routing in ReactJs

Useful Resources and Links

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