Categories
React Vue

React vs Vue — Handling Form Input

React is the most popular front end library for the last few years.

Vue is a front end framework that’s catching up in popularity with React in the last few years.

It’s hard to choose between the 2 frameworks since they both their pros and cons. When we choose one, we’ve to stick with it for a few years.

In this article, we’ll look at how we handle form input with React and Vue and which is better for developers.

Handling Form Input Values.

To handle form values with React, we have to add a onChange handler in each input to set the value of the input in the state.

For example, if we have multiple inputs in our form, then we have to write the following code to do that:

import React, { useState } from "react";

export default function App() {
  const [person, setPerson] = useState({});
  const onSubmit = e => {
    e.preventDefault();
    alert(`${person.firstName} ${person.lastName}`);
  };

  return (
    <div className="App">
      <form onSubmit={onSubmit}>
        <input
          name="firstName"
          placeholder="First Name"
          onChange={e => setPerson({ ...person, firstName: e.target.value })}
        />
        <br />
        <input
          name="lastName"
          placeholder="Last Name"
          onChange={e => setPerson({ ...person, lastName: e.target.value })}
        />
        <br />
        <input type="submit" value="Submit" />
      </form>
    </div>
  );
}

In the code above, we have 2 inputs with onChange handlers added to both to put the value that’s entered into the person object.

Then we update the value by calling setPerson with the object.

Once we did that, we can get the latest value of person in our onSubmit handler once we click Submit.

With all the onChange handlers we have to add, it definitely gets tedious when our for has lots of inputs.

The Vue equivalent of the code above would be the following:

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <form @submit.prevent="onSubmit">
        <input
          name="firstName"
          placeholder="First Name"
          v-model="person.firstName"
        />
        <br />
        <input
          name="firstName"
          placeholder="Last Name"
          v-model="person.lastName"
        />
        <br />
        <input type="submit" value="Submit" />
      </form>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js :

const app = new Vue({
  el: "#app",
  data: {
    person: {
      firstName: "",
      lastName: ""
    }
  },
  methods: {
    onSubmit() {
      alert(`${this.person.firstName} ${this.person.lastName}`);
    }
  }
});

The Vue has the same form, but we can bind the input value to our Vue’s data value by using the v-model directive.

This is shorter than adding an onChange handler to every input that we have in our form.

Also, to call preventDefault , we can just write: .prevent instead of calling it explicitly, which is a nice shortcut that’s not available in React.

Handling form input is definitely cleaner with Vue than with React.

Handling Checkboxes

We can bind our checkbox choices to the Vue component’s model by setting the v-model directive to the same array.

For example, we can write the following code to do that:

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <input type="checkbox" value="Jane" v-model="checkedNames" />
      <label>Jack</label>
      <input type="checkbox" value="Mary" v-model="checkedNames" />
      <label>John</label>
      <input type="checkbox" value="Mike" v-model="checkedNames" />
      <label>Mike</label>
      <br />
      <span>Checked names: {{ checkedNames }}</span>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js :

const app = new Vue({
  el: "#app",
  data: {
    checkedNames: []
  }
});

As we can see, we just have to declare the checkNames model in the data object and then we just set the value of v-model to checkedNames to get all the values that are checked.

With React, we have to update the value of each checkbox with an onChange handler that combines the old values with the new values, then we display the checked values by filtering out the ones that aren’t checked.

We write the following to do that:

import React, { useState } from "react";

export default function App() {
  const [checkedNames, setCheckedNames] = useState({});
  const handleCheck = e =>
    setCheckedNames({
      ...checkedNames,
      [e.target.value]: e.target.checked
    });

  return (
    <div className="App">
      <input type="checkbox" value="Jane" onChange={handleCheck} />
      <label>Jack</label>
      <input type="checkbox" value="Mary" onChange={handleCheck} />
      <label>John</label>
      <input type="checkbox" value="Mike" onChange={handleCheck} />
      <label>Mike</label>
      <br />
      <span>
        Checked names:{" "}
        {Object.keys(checkedNames)
          .filter(name => checkedNames[name])
          .join(", ")}
      </span>
    </div>
  );
}

In the code above, we created a handleCheck function to combine the existing checkbox entries, which has the value of the checkbox as the key and the checked value of each checkbox as the value.

Then to display the values that are checked, we have to filter out the ones that aren’t checked and then convert the resulting array to a string.

This is definitely much more work than just binding the values to v-model and then displaying an array as-is on the template in the Vue version.

Verdict

Vue’s v-model really takes the hard work out of form handling. Text input is easy to handle, and checkboxes are even more so.

To handle form values with React, we need onChange handlers for every input.

As we can see, if handling the value of a simple set of checkboxes is so complex with React, then if we have more inputs in a form, then it’s going to get even more complex.

We have to add a few lines of code just to display the checked values in the React example, which isn’t ideal.

Categories
React Vue

React vs Vue — Setting Attributes and Displaying Collections

React has been the most popular front end library for the last few years.

Vue is a front end framework that’s catching up in popularity with React and has an incredibly passionate developer community adopting it.

It’s hard to choose between the 2 frameworks since they both have their pros and cons. When we choose one, we’ve to stick with it for a few years.

In this article, we’ll look compare the setting attribute and displaying collections with React and Vue.

Setting Attributes

With React, we can set attributes like HTML. But we can also set dynamic attributes in our app.

For example, we can write the following code to do that:

import React, { useState } from "react";

export default function App() {
  const [color, setColor] = useState("red");
  const toggleColor = () => {
    setColor(color === "red" ? "green" : "red");
  };

  return (
    <div className="App">
      <button onClick={toggleColor}>Toggle</button>
      <div className="box" style={{ color }}>
        foo
      </div>
    </div>
  );
}

In the code above, we set the color of the div dynamically with the useState hook, which returns the setColor function to let us set the color.

Then we pass in the color to the style attribute. To set a static class name for our div, we have to use the className attribute. We have to remember differences like className instead of class when we set attributes with React.

With Vue, we put our data and methods in the component and set the static and dynamic attributes as follows:

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <button @click="toggleColor">Toggle</button>
      <div class="box" :style="{color: color}">
        foo
      </div>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js:

const app = new Vue({
  el: "#app",
  data: {
    color: "red"
  },
  methods: {
    toggleColor() {
      this.color = this.color === "red" ? "green" : "red";
    }
  }
});

With Vue, we have to add the toggleColor method to the method and a default value for the color field in the data object.

Then we have to add the same logic for setting the color in the toggleColor method.

This is more complex than what we have with React. However, it does separate the logic for display and business logic into separate parts.

This is easier to deal with when our components are more complex.

Displaying Collections

We can display collections with React by mapping our arrays to a collection of components.

For example, if we have an array of names, we can write the following to display them with React:

import React, { useState } from "react";

export default function App() {
  const [persons] = useState([
    { name: "Mary" },
    { name: "John" },
    { name: "Joe" }
  ]);

  return (
    <div className="App">
      {persons.map(p => (
        <div>{p.name}</div>
      ))}
    </div>
  );
}

In the code above, we have the persons array, which is then mapped to divs with p.name as the text content.

To do the same thing with Vue, we can write the following:

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <div v-for="p of persons">
        {{p.name}}
      </div>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js:

const app = new Vue({
  el: "#app",
  data: {
    persons: [{ name: "Mary" }, { name: "John" }, { name: "Joe" }]
  }
});

In the code above, we have the persons array in the Vue component, and the v-for directive to display items in the persons array.

This is cleaner than what we have with React. We keep the code in each file more compact.

This will be even more apparent is more components are more complex, which is often the case.

Another good thing about v-for is that we can use them to iterate through entries of an object as well.

For example, we can write the following to do that:

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <div v-for="(age, name) in persons">
        {{name}}: {{age}}
      </div>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js:

const app = new Vue({
  el: "#app",
  data: {
    persons: {
      John: 20,
      Mary: 19,
      Jane: 20
    }
  }
});

We can get the value and key of an object’s entry respectively with:

v-for="(age, name) in persons"

With React, we use Object.entries to do the same thing:

import React, { useState } from "react";

export default function App() {
  const [persons] = useState({
    John: 20,
    Mary: 19,
    Jane: 20
  });

  return (
    <div className="App">
      {Object.entries(persons).map(([name, age]) => (
        <div>
          {name}: {age}
        </div>
      ))}
    </div>
  );
}

The expression is getting more complex since we have to call Object.entries and then map them to the component that we want to render.

Verdict

For simple components, there isn’t too much difference between React and Vue when it comes to setting attributes.

However, we do have to remember that they’re all camel case and the names might be different from HTML.

Vue has a slight edge here since we don’t have to worry about that. Dynamic attributes can be set with : and the rest is the same.

With Vue, we have to learn the v-for directive to render collections, while we just use plain JavaScript to do that with React.

However, with React, we have to write one big expression to do that, while in Vue, we can add directives to a template to do that.

This makes rendering collections cleaner with Vue, so Vue has the slight edge here as well.

Categories
React

React Patterns — Improving Performance and Avoid Antipatterns

React is a popular library for creating web apps and mobile apps.

In this article, we’ll look at how to improve the performance and avoiding antipatterns when we create React apps.

Reconciliation and keys

We’ve to add a key to the key prop that’s unique.

Otherwise, React can’t keep track of the list items properly.

For instance, we can write:

{items.map(item => <li key={item.id}>{item.name}</li>)}

We got to have an id property that’s unique with for each items entry.

The items that are inserted can’t be tracked without a unique ID in the key prop.

useEffect

We should watch the items that we need to watch to update a derived value.

To do that we use the useEffect hook.

For instance, we write:

useEffect(() => {
  doSomething(foo);
}, [foo]);

Now we call doSomething only when foo updates.

This is the hooks equivalent of shouldComponentUpdate and componentWillReceiveProps .

It works with both props and state changes.

Stateless Function Components

Stateless function components don’t give any benefits with regards to performance.

It just helps us make presentation only components to separate logic from components with states.

useMemo

We can use the useMemo hook to store results from expensive computations.

For instance, we can write:

const memoizedValue = useMemo(() => compute(a, b), [a, b]);

Now React won’t compute the value again unless a or b changed.

Refactoring and Good Design

We should have states with descriptive names.

items is a good name for a state that stores some items.

If we have something more specific then we should name it with that.

We should only render when something changes.

If props and state change, then we render.

Immutability

We should make things immutable when we can,

This way, they can’t be mutated accidentally.

Then we can avoid this kind of bugs, which may be hard to trace.

To avoid mutation, we can make a copy of an object and then change it.

We can use Object.assign or spread to do that:

const newObj = Object.assign({}, obj, { foo: 'bar' });

or:

const newObj = {...obj,  foo: 'bar' };

Likewise, we can do the same with arrays.

For instance, we can write:

const newArr = [...arr, 1];

We used the spread operator to spread the arr array entries into a new array and add 1 to it.

Initializing the State using Props

We shouldn’t initialize the state using props.

Instead, we should watch for prop changes and then update the state accordingly.

This way, we’ll make sure our props are updated with the state.

To do that, we use the useEffect hook as follows:

useEffect(() => {
  setBar(foo);
}, [foo]);

If foo is a prop, then we can set the bar state with setBar by calling it with foo so that the bar state is updated when foo is updated.

Mutating the State

Also, we shouldn’t mutate the state directly.

If we have a state, then we shouldn’t assign it with a new value direcyly.

Instead, we call the function to set the state.

For instance, we can write:

setCount(2);

top set the state, where setCount is the function returned by useState to set the count state.

Or we can write:

setCount(count => count + 1);

if we want to set a state based on the previous count state’s value.

We should do that as little as possible to improve performance.

Using Indexes as a Key

Indexes shouldn’t be used as the key if possible.

This is because tracking can’t be done properly with indexes as keys, then if we modify the array of elements or components, then we would have problems.

The best value for the key prop is a unique ID of the item.

Spreading Props on DOM Elements

We should avoid spreading props to DOM elements to avoid spreading unknown HTML attributes, which is a bad practice.

We may get errors from React telling us to remove unknown attributes.

Instead, we should just write them out explicitly unlike props.

Conclusion

We should think about performance and antipatterns when we’re writing React components.

It’s hard to create components that are speedy and do everything we want.

But if we take into account some good practices, we can do it easily.

Categories
React

React Antipatterns to Avoid

React is the most used front end library for building modern, interactive front end web apps. It can also be used to build mobile apps.

In this article, we’ll look at some React antipatterns that we should avoid.

bind() and Functions in Components

When we call bind in React class components, we shouldn’t call them repeatedly in our props. Instead, we should call bind in the constructor so that we don’t have to call bind on the fly when we pass in our class component methods as props.

For instance, we can write the following code to do that:

import React from "react";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: ""
    };
    this.updateValue = this.updateValue.bind(this);
  }
  updateValue(e) {
    this.setState({
      name: e.target.value
    });
  }
  render() {
    return (
      <>
        <form>
          <input onChange={this.updateValue} value={this.state.name} />
        </form>
        <p>{this.state.name}</p>
      </>
    );
  }
}

In the code above, we have an input which calls the updateValue method when the input value is changed.

We have:

this.updateValue = this.updateValue.bind(this);

in the constructor so that it’ll always bind the component as the value of this .

Now we don’t have to do it again repeatedly everywhere. Also, we won’t be creating a new function every time the onChange event is emitted since we didn’t call bind , which returns a new function.

The performance hit from creating methods on the fly when our app grows large is going to be noticeable in some situations.

So instead of writing:

<input onChange={this.updateValue.bind(this)} value={this.state.name} />

we write what we have above.

Missing key Prop or Using indexes in key Prop

The key prop is important when we render lists, even though it may seem like it’s doing nothing sometimes. The unique key prop value lets React identify list items correctly.

key prop values are used to match the children in the original tree with the children in the subsequent tree.

Therefore, using the array’s index is also bad because it may lead React to render the wrong data.

It’s best to use unique IDs as the value of the key prop. We can create an array with unique IDs that we can use as keys as follows:

import React from "react";
import { v4 as uuidv4 } from "uuid";

const arr = [
  {
    fruit: "apple",
    id: uuidv4()
  },
  {
    fruit: "orange",
    id: uuidv4()
  },
  {
    fruit: "grape",
    id: uuidv4()
  }
];

export default function App() {
  return (
    <div className="App">
      {arr.map(a => (
        <p key={arr.id}>{a.fruit}</p>
      ))}
    </div>
  );
}

In the code above, we used the uuid package to create a unique UUID to use as the value of the key prop. This way, there’s almost no chance of collision of unique IDs.

This way, IDs are unique and predictable, and we don’t have to think of a way to generate the unique ID for each item ourselves.

Components Name

Component names have to begin with a capital letter. For instance, if we write the following code, we’ll get an error from React:

import React from "react";

const foo = () => <p>foo</p>;

export default function App() {
  return (
    <div className="App">
      <foo />
    </div>
  );
}

If we run the code above, React will give us the error ‘<foo> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.’

Therefore, we should instead name our components always with a capital letter to start:

import React from "react";

const Foo = () => <p>foo</p>;

export default function App() {
  return (
    <div className="App">
      <Foo />
    </div>
  );
}

Then we’ll see ‘foo’ displayed on the screen as we expected.

Photo by chatnarin pramnapan on Unsplash

Close Every Element

All component tags have to have a closing tag or a slash in the end for self-closing components. For instance, if we have:

import React from "react";

const Foo = () => <p>foo</p>;

export default function App() {
  return (
    <div className="App">
      <Foo>
    </div>
  );
}

We’ll get a syntax error because we’re missing a closing slash or tag in:

<Foo>

To make the app run, we write instead:

import React from "react";

const Foo = () => <p>foo</p>;

export default function App() {
  return (
    <div className="App">
      <Foo />
    </div>
  );
}

<Foo></Foo> also works.

Conclusion

It’s easy to make mistakes when we’re writing React components. We have to remember to capitalize the first letter of component names. Also, we have to close the tags of the component or add a closing slash for self-closing components.

Also, we should call bind first so that we don’t have to call it repeatedly to bind to the right value of this in class-based components.

Categories
React

How To Build a Static Site With Gatsby.js

If you want to build a static website or a blog and you know web development, you have many choices of static website generators.

If you want to use React to build your static website, Gatsby could be a choice that suits your needs. It is used by many large corporations to build their websites, according to the Gatsby website.

In this piece, we will use Gatsby to build a small blog with pagination for blog posts and a menu which lets readers get categories. Once the reader clicks on the link for a category, they will go to a page listing all the posts tagged with those categories.

Gatsby can get content from files and from network sources like an API endpoint. Content is obtained through GraphQL endpoints which you can message to display data in a way you want, via templates.

You can also build static page files that display contents that don’t change. You write the code to get the content and display them with templates.

Then, you build the static web pages from the code you wrote. Plugins for Gatsby will provide the functionality that you want.

There are a few hoops to go through to build a static website or blog. Also, you cannot use most third-party React components with Gatsby as they are dynamic.

Also, the command-line utility has problems with case-sensitive paths on Windows, causing RelayParser: Encountered duplicate definitions for one or more documents from duplicate case-insensitive file paths in various parts of the project folder.

Therefore, Linux or Mac OS are probably the best choices for using the Gatsby CLI. Also, multiple page queries have to be made in one file and you pipe them all to templates in the same file.

The gatsby-node.js in the project is where the query for content takes place.

Now that we are aware of the caveats, we can start building our website. We will build a blog with some blog entries. The layout of the blog is a header for the top and content on the rest of the page.

We will have a template for displaying all the blog entries with pagination with five posts each. Also, we will have a categories page for displaying the list of articles with the given tag. We will use Bootstrap for styling.

We start by installing the Gatsby CLI by running npm install -g gatsby-cli. Once that is installed, we run the CLI program to add the initial code for the website. We run gatsby new gatsby-blog to build a new site.

Next, we install some add-on packages for Gatsby to do things like getting content from markdown files and displaying images.

Install the packages by running:

npm i @mdx-js/mdx @mdx-js/react bootstrap gatsby-image gatsby-paginate gatsby-plugin-manifest gatsby-plugin-mdx gatsby-plugin-offline gatsby-plugin-react-helmet gatsby-plugin-sharp gatsby-remark-images gatsby-source-filesystem gatsby-transformer-remark gatsby-transformer-sharp jquery lodash popper.js react-helmet

The main packages on this list are gatsby-image for displaying images, gatsby-source-filesystem for getting the markdown files and displaying them in our templates.

react-helmet for adding a head tag to our blog for including external CSS and script files. gatsby-transformer-remark is for converting markdown into HTML text. gatsby-transformer-sharp is for transforming images from various sources to display on our website.

With the package installation out of the way, we can start writing code. In the components folder, we first work on header.js.

In there, we put:

import { Link } from "gatsby"
import PropTypes from "prop-types"
import React from "react"
import { StaticQuery, graphql } from "gatsby"
import _ from "lodash"
import "./header.css"

const Header = ({ siteTitle }) => (
  <nav className="navbar navbar-expand-md bg-dark navbar-dark">
    <a className="navbar-brand" href="#">
      {siteTitle}
    </a>

    <button
      className="navbar-toggler"
      type="button"
      data-toggle="collapse"
      data-target="#collapsibleNavbar"
    >
      <span className="navbar-toggler-icon"></span>
    </button>
    <div className="collapse navbar-collapse" id="collapsibleNavbar">
      <ul className="navbar-nav">
        <li className="nav-item">
          <Link to="blog/page/1" className="nav-link">
            Home
          </Link>
        </li>
        <li className="nav-item dropdown">
          <a
            className="nav-link dropdown-toggle"
            href="#"
            id="navbarDropdown"
            role="button"
            data-toggle="dropdown"
            aria-haspopup="true"
            aria-expanded="false"
          >
            Categories
          </a>
          <div className="dropdown-menu" aria-labelledby="navbarDropdown">
            <StaticQuery
              query={graphql`
                query CategoryQuery {
                  allMarkdownRemark(limit: 2000) {
                    group(field: frontmatter___tags) {
                      fieldValue
                    }
                  }
                }
              `}
              render={data => {
                return data.allMarkdownRemark.group.map(g => {
                  return (
                    <Link
                      to={`tags/${g.fieldValue}`}
                      className="dropdown-item"
                    >
                      {_.capitalize(g.fieldValue)}
                    </Link>
                  )
                })
              }}
            />
          </div>
        </li>
      </ul>
    </div>
  </nav>
)

Header.propTypes = {
  siteTitle: PropTypes.string,
}

Header.defaultProps = {
  siteTitle: ``,
}

export default Header

This adds the Bootstrap navigation bar to our app. We get the tags for all our posts and display them in a drop-down in the navigation bar.

In header.css, we put:

.navbar-brand {
  font-size: 20px;
  margin-top: -20px;
}

nav.navbar {
  padding-bottom: 0px;
  height: 60px;
}

To change the height of the navigation bar and change font sizes and margins.

Next, we work on the common layout for the blog. We create a file called layout.js in the components folder, if it does not exist yet, and add:

/**
 * Layout component that queries for data
 * with Gatsby's useStaticQuery component
 *
 * See: [https://www.gatsbyjs.org/docs/use-static-query/](https://www.gatsbyjs.org/docs/use-static-query/)
 */

import React from "react"
import PropTypes from "prop-types"
import { useStaticQuery, graphql } from "gatsby"
import { Helmet } from "react-helmet"
import Header from "./header"
import "./layout.css"

const Layout = ({ children }) => {
  const data = useStaticQuery(graphql`
    query SiteTitleQuery {
      site {
        siteMetadata {
          title
        }
      }
    }
  `)

  return (
    <>
      <Helmet>
        <title>Gatsby Blog</title>
        <script
          src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
          integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
          crossOrigin="anonymous"
        ></script>
        <script
          src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
          integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
          crossOrigin="anonymous"
        ></script>
        <script
          src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
          integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
          crossOrigin="anonymous"
        ></script>
        <link
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
          rel="stylesheet"
          integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
          crossOrigin="anonymous"
        />
      </Helmet>
      <Header siteTitle={data.site.siteMetadata.title} />
      <div
        style={{
          margin: `0 auto`,
          maxWidth: 960,
          padding: `0px 1.0875rem 1.45rem`,
          paddingTop: 0,
        }}
      >
        <main>{children}</main>
        <footer>
          © {new Date().getFullYear()}, Built with
          {` `}
          <a href="https://www.gatsbyjs.org">Gatsby</a>
        </footer>
      </div>
    </>
  )
}

Layout.propTypes = {
  children: PropTypes.node.isRequired,
}

export default Layout

In this file, we add the head tag for our HTML pages. We include the Bootstrap CSS and code files and jQuery in the Helmet component, which will be converted to the head tag in our pages.

Next, we add our content, create a markdown-pages folder in the src folder. Then, we create some markdown files.

We add the following files into the markdown-pages folder:

check-variable-number.md
clone-array.md
concat-array.md
exponentiation.md
get-length-obj.md
repeat-string.md
send-email.md

Then, in check-variable-number.md, we add:

---
path: "/blog/check-variable-number"
date: "2019-05-04"
title: "How to Check if a Variable is a Number"
tags: ["number"]
---

We can check if a variable is a number in multiple ways.

## isNaN

We can check by calling `isNaN` with the variable as the argument. It also detects if a string’s content is a number. For example:

isNaN(1) // false isNaN(‘1’) // false isNaN(‘abc’) // true


**Note:** `isNaN(null)` is `true` .

### typeof Operator

We can use the `typeof` operator before a variable to check if it’s a number, like so:

typeof 1 == ‘number’ // true typeof ‘1’ == ‘number’ // false


![]([https://cdn-images-1.medium.com/max/800/1*3X6EiKc-njoRpCB1AWnv3Q.png](https://cdn-images-1.medium.com/max/800/1*3X6EiKc-njoRpCB1AWnv3Q.png))

In clone-array.md, we add:

---
path: "/blog/clone-array"
date: "2019-05-04"
title: "How to Clone Array in JavaScript"
tags: ["array"]
---

There are a few ways to clone an array in JavaScript,

### Object.assign

`Object.assign` allows us to make a shallow copy of any kind of object including arrays.

For example:

<pre>const a = [1,2,3];
const b = Object.assign([], a); // [1,2,3]</pre>

### Array.slice

The `Array.slice` function returns a copy of the original array.

For example:

<pre>const a = [1,2,3];
const b = a.slice(0); // [1,2,3]</pre>

### Array.from

The `Array.slice` function returns a copy of the original array. It takes array like objects like `Set` and it also takes an array as an argument.

<pre>const a = [1,2,3];
const b = Array.from(a); // [1,2,3]</pre>

### Spread Operator

The fastest way to copy an array, which is available with ES6 or later, is the spread operator.

<pre>const a = [1,2,3];
const b = [...a]; // [1,2,3]</pre>

### JSON.parse and JSON.stringify

This allows for deep copy of an array and only works if the objects in the array are plain objects. It can be used like this:

<pre>const a = [1,2,3];
const b = JSON.parse(JSON.stringify(a)); // [1,2,3]</pre>

Next, in concat-array.md, we add:

---
path: "/blog/concat-array"
date: "2019-05-04"
title: "How to Concatenate Array in JavaScript"
tags: ["array"]
---

There are a few ways to concatenate arrays in JavaScript.

## Array.concat

We can all `Array.concat` on an array to combine 2 arrays and return the new one. For example:

const a = [1,2,3]; const b = [4,5]; const c = a.concat(b) // [1,2,3,4,5]


## Array.push

We can push elements of one array into another.

const a = [1,2,3]; const b = [4,5]; let c = Object.assign([], a); for (let i = 0; i < b.length; i++){ c.push(b[i]); } console.log(c); // [1,2,3,4,5]


What we did is make a copy of `a` and assigned it to `c` , then pushed the elements of `b` by looping through it and adding them to the end of `c` .

## Spread Operator

With ES6 or later, we can use the spread operator to spread the items from another array into a new array by doing the following:

const a = [1,2,3]; const b = [4,5]; const c = […a, …b]; console.log(c); // [1,2,3,4,5]


![]([https://cdn-images-1.medium.com/max/800/1*3X6EiKc-njoRpCB1AWnv3Q.png](https://cdn-images-1.medium.com/max/800/1*3X6EiKc-njoRpCB1AWnv3Q.png))

In exponentiation.md, we add:

---
path: "/blog/exponentiation"
date: "2019-05-04"
title: "How to do Exponentiation in JavaScript"
tags: ["number"]
---

There are multiple to compute exponents with JavaScript.

The newest way is the exponentiation operator `**`, available with ES2016 or higher.

For example, we can do this:

const a = 2 ** 3; // 8


It is right associative, so `a ** b ** c` is equal to `a ** (b ** c)`. This works with all exponents.

For example:

const a = 2 ** (3 ** 4); const b = 2 ** 3 ** 4; a == b // true, both are 2.4178516392292583e+24


Detail browser compatibility is available at [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Browser_compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Browser_compatibility)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Browser_compatibility]%28https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Browser_compatibility%29)

We can also use the `Math.pow` function, like this:

const a = Math.pow(2,3) // 8


It takes 2 arguments, the first is the base and the second is the exponent. `Math.pow` works with all exponents.

`Math.pow` is compatible with all recent browsers.

![]([https://cdn-images-1.medium.com/max/800/1*3X6EiKc-njoRpCB1AWnv3Q.png](https://cdn-images-1.medium.com/max/800/1*3X6EiKc-njoRpCB1AWnv3Q.png))

In get-length-obj.md, we add:

---
path: "/blog/get-length-obj"
date: "2019-05-04"
title: "How to Get the Length of An Object"
tags: ["object"]
---

There are 2 ways to get the length of the list of keys of an object.

## Object.keys

`Object.keys` gets the top level list of keys of an object and returns an array of them. For example:

const a = {foo: 1, bar: 2}; const length = Object.keys(a).length // 2


## Object.getPropertyNames

`Object.getPropertyNames` also gets a list of all top level of keys of an object and return them as an array. For example:

const a = {foo: 1, bar: 2}; const length = Object.getOwnPropertyNames(a).length // 2


## for…in Loop

There is a special loop for looping through the keys of an object. You can do the following:

const a = {foo: 1, bar: 2}; let keysCount = 0; for (let key in a) { keysCount++; } console.log(`keysCount) // 2


![]([https://cdn-images-1.medium.com/max/800/1*3X6EiKc-njoRpCB1AWnv3Q.png](https://cdn-images-1.medium.com/max/800/1*3X6EiKc-njoRpCB1AWnv3Q.png))

In repeat-strings.md, we add:

---
path: "/blog/repeat-strings"
date: "2019-05-04"
title: "How to Repeat Strings with JavaScript"
tags: ["string"]
---

There are a few ways to repeat a string in JavaScript. JavaScript strings have a built in `repeat()` function. You can also use a loop to do the same thing.

## String.repeat Function

To use the `repeat` function, you pass in the number of times you want to repeat the string as an argument. It returns a new string

For example:

const hello = "hello"; const hello5 = A.repeat(5); console.log(hello5); // "hellohellohellohellohello"


## Use a loop

You can use `for` loop and `while` loop to do repeatedly concatenate strings.

Using a `for` loop, you can do:

const hello = "hello";


With a `while` loop, you can do:

const hello = "hello";


They both involve increment indexes up to the maximum.

![]([https://cdn-images-1.medium.com/max/800/1*3X6EiKc-njoRpCB1AWnv3Q.png](https://cdn-images-1.medium.com/max/800/1*3X6EiKc-njoRpCB1AWnv3Q.png))

In send-email.md, we add:

---
path: "/blog/send-email"
date: "2019-05-04"
title: "How to Send Email with SendGrid in Node.js Apps"
tags: ["array"]
---

SendGrid is a great service made by Twilio for sending emails. Rather than setting up your own email server for sending email with your apps, we use SendGrid to do the hard work for us. It also decrease the chance of email ending up in spam since it is a known trustworthy service.

It also has very easy to use libraries for various platforms for sending emails. Node.js is one of the platforms that are supported.

To send emails with SendGrid, install the SendGrid SDK package by running `npm i [@sendgrid/mail](http://twitter.com/sendgrid/mail "Twitter profile for @sendgrid/mail")` . Then in your code, add `const sgMail = require(‘[@sendgrid/mail](http://twitter.com/sendgrid/mail "Twitter profile for @sendgrid/mail")’);` to import the installed package.

Then in your code, you send email by:

sgMail.setApiKey(process.env.SENDGRID_API_KEY); const msg = { to: email, from: ‘email@example.com‘, subject: ‘Example Email’, text: Dear user, Here is your email., html: <p>Dear user,</p></pre> Here is your email.</p>, }; sgMail.send(msg);


where `process.env.SENDGRID_API_KEY` is the SendGrid’s API, which should be stored as an environment variable since it is a secret.

Testing is easy since you don’t need to set up a local development email server.

Sending email is this simple and easy with SendGrid API. It is also free if you send small amounts of email, which is a great benefit.

![]([https://cdn-images-1.medium.com/max/800/1*EdbfsnL3ABxWj2iVWmoIWA.png](https://cdn-images-1.medium.com/max/800/1*EdbfsnL3ABxWj2iVWmoIWA.png))

In each file, we have the metadata between the dotted lines. They will be obtained from GraphQL queries and can be displayed on our pages, and we will display them.

Now that we’ve worked on our content, we can work on the static pages. We change default 404 pages by adding the top navigation bar.

In 404.js, we replace the existing code with:

import React from "react"

import Layout from "../components/layout"
import SEO from "../components/seo"
import Header from "../components/header";

const NotFoundPage = () => (
  <Layout>
    <SEO title="404: Not found" />
    <h1>NOT FOUND</h1>
    <p>You just hit a route that doesn&#39;t exist... the sadness.</p>
  </Layout>
)

export default NotFoundPage

Everything in the Layout component will be applied to this page, including the navigation bar and Bootstrap styles.

In index.js, we replace the existing code with:

import React from "react"

import Layout from "../components/layout"
import SEO from "../components/seo"
import { useEffect } from "react"
import { navigate } from "gatsby"

const IndexPage = () => {
  useEffect(() => {
    navigate("/blog/page/1")
  }, [])

  return (
    <Layout>
      <SEO title="Home" />
    </Layout>
  )
}

export default IndexPage

To redirect to our blog template, which we will create.

Next, we create our templates. We create a templates folder in the src folder to store our templates.

In there, create blog-list-template.js and add:

import React from "react"
import { graphql, Link } from "gatsby"
import Layout from "../components/layout"
export default class BlogList extends React.Component {
  constructor(props) {
    super(props)
    this.state = { pageNumArray: [1] }
  }

  componentDidMount() {
    this.setPageArray()
  }

  componentWillReceiveProps() {
    this.setPageArray()
  }

  setPageArray() {
    const totalCount = this.props.data.allMarkdownRemark.totalCount
    const postsPerPage = this.props.data.allMarkdownRemark.pageInfo.perPage
    let pageNumArray = Array.from(
      { length: Math.ceil(totalCount / postsPerPage) },
      (v, i) => i + 1
    )
    this.setState({ pageNumArray })
  }

render() {
    const posts = this.props.data.allMarkdownRemark.edges
    const pathNames = this.props.location.pathname.split("/")
    const page = pathNames[pathNames.length - 1]
    return (
      <Layout>
        {posts.map(({ node }) => {
          const title = node.frontmatter.title || node.fields.slug
          return (
            <div key={node.fields.slug}>
              <h1>{title}</h1>
              <b>Date Posted: {node.frontmatter.date}</b>
              <div dangerouslySetInnerHTML={{ __html: node.html }} />
            </div>
          )
        })}
        <nav aria-label="Page navigation example">
          <ul className="pagination">
            {this.state.pageNumArray.map(p => (
              <li className={`page-item ${page == p ? "active" : ""}`} key={p}>
                <Link className={`page-link`} to={`blog/page/${p}`}>
                  {p}
                </Link>
              </li>
            ))}
          </ul>
        </nav>
      </Layout>
    )
  }
}
export const blogListQuery = graphql`
  query blogListQuery($skip: Int!, $limit: Int!) {
    allMarkdownRemark(
      sort: { fields: [frontmatter___date], order: DESC }
      limit: $limit
      skip: $skip
    ) {
      edges {
        node {
          fields {
            slug
          }
          frontmatter {
            title
            date
          }
          html
        }
      }
      pageInfo {
        perPage
      }
      totalCount
    }
  }
`

In here, display the content that is providing the query that we will add in gatsby-node.js.

The blogListQuery filters the content by running the query and returning the results. Then, the results will be displayed in the component above.

The setPageArray function gets the page numbers by getting the total number of pages and then setting it in the component state so that we can have links to go the page, which is rendered by:

{this.state.pageNumArray.map(p => (
   <li className={`page-item ${page == p ? "active" : ""}`} key={p}>
     <Link className={`page-link`} to={`blog/page/${p}`}>
     {p}
     </Link>
   </li>
))}

The blog posts are rendered by:

{posts.map(({ node }) => {
  const title = node.frontmatter.title || node.fields.slug
  return (
    <div key={node.fields.slug}>
      <h1>{title}</h1>
      <b>Date Posted: {node.frontmatter.date}</b>
      <div dangerouslySetInnerHTML={{ __html: node.html }} />
      </div>
  )
})}

Gatsby sanitizes HTML so we can display it by setting it directly with dangerouslySetInnerHTML. Next, we make a template to display the posts with certain tags.

To do this, we create tags.js in the templates folder and add:

import React from "react"
import PropTypes from "prop-types"
import Layout from "../components/layout"
import _ from "lodash"
// Components
import { Link, graphql } from "gatsby"

const Tags = ({ pageContext, data }) => {
  const { tag } = pageContext
  const { edges, totalCount } = data.allMarkdownRemark
  const tagHeader = `${totalCount} post${
    totalCount === 1 ? "" : "s"
  } tagged with "${_.capitalize(tag)}"`

  return (
    <Layout>
      <h1>{tagHeader}</h1>
      {edges.map(({ node }) => {
        const { slug } = node.fields
        const { title, date } = node.frontmatter
        return (
          <div key={slug}>
            <h1>{title}</h1>
            <b>Date Posted: {date}</b>
            <div dangerouslySetInnerHTML={{ __html: node.html }} />
          </div>
        )
      })}
    </Layout>
  )
}

Tags.propTypes = {
  pageContext: PropTypes.shape({
    tag: PropTypes.string.isRequired,
  }),
  data: PropTypes.shape({
    allMarkdownRemark: PropTypes.shape({
      totalCount: PropTypes.number.isRequired,
      edges: PropTypes.arrayOf(
        PropTypes.shape({
          node: PropTypes.shape({
            frontmatter: PropTypes.shape({
              title: PropTypes.string.isRequired,
            }),
            fields: PropTypes.shape({
              slug: PropTypes.string.isRequired,
            }),
          }),
        }).isRequired
      ),
    }),
  }),
}

export default Tags

export const pageQuery = graphql`
  query($tag: String) {
    allMarkdownRemark(
      limit: 2000
      sort: { fields: [frontmatter___date], order: DESC }
      filter: { frontmatter: { tags: { in: [$tag] } } }
    ) {
      totalCount
      edges {
        node {
          fields {
            slug
          }
          frontmatter {
            title
            date
          }
          html
        }
      }
    }
  }
`

It works similarly to blog-list-template.js. The GraphQL query at the bottom gets the posts tagged with the given tag and then displays them by running the component code above.

The metadata of our pages is in the frontmatter object of each entry.

Next, in gatsby-config.js, we replace the existing code with:

module.exports = {
  siteMetadata: {
    title: `Gatsby Blog`,
    description: `Gatsby Blog`,
    author: `[@gatsbyjs](http://twitter.com/gatsbyjs "Twitter profile for @gatsbyjs")`,
  },
  plugins: [
    `gatsby-plugin-react-helmet`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-plugin-mdx`,
      options: {
        gatsbyRemarkPlugins: [
          {
            resolve: `gatsby-remark-images`,
            options: {
              maxWidth: 1200,
            },
          },
        ],
      },
    },
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `gatsby-starter-default`,
        short_name: `starter`,
        start_url: `/blog/page/1`,
      },
    },
    // this (optional) plugin enables Progressive Web App + Offline functionality
    // To learn more, visit: [https://gatsby.dev/offline](https://gatsby.dev/offline)
    // `gatsby-plugin-offline`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `markdown-pages`,
        path: `${__dirname}/src/markdown-pages`,
      },
    },
    `gatsby-plugin-react-helmet`,
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          {
            resolve: `gatsby-remark-images`,
            options: {
              // It's important to specify the maxWidth (in pixels) of
              // the content container as this plugin uses this as the
              // base for generating different widths of each image.
              maxWidth: 590,
            },
          },
        ],
      },
    },
  ],
}

So that all the packages we installed run.

Finally, in gatsby-node.js, we replace the existing code with:

const _ = require("lodash")
const path = require("path")
const { createFilePath } = require("gatsby-source-filesystem")

exports.createPages = async ({ graphql, actions, reporter }) => {
  const { createPage } = actions
  const result = await graphql(
    `
      {
        postRemark: allMarkdownRemark(
          sort: { fields: [frontmatter___date], order: DESC }
          limit: 1000
        ) {
          edges {
            node {
              fields {
                slug
              }
            }
          }
        }
        tagsGroup: allMarkdownRemark(limit: 2000) {
          group(field: frontmatter___tags) {
            fieldValue
          }
        }
      }
    `
  )
  if (result.errors) {
    reporter.panicOnBuild(`Error while running GraphQL query.`)
    return
  }
  // ...
  // Create blog-list pages
  const posts = result.data.postRemark.edges
  const postsPerPage = 5
  const numPages = Math.ceil(posts.length / postsPerPage)
  Array.from({ length: numPages }).forEach((_, i) => {
    createPage({
      path: `/blog/page/${i + 1}`,
      component: path.resolve("./src/templates/blog-list-template.js"),
      context: {
        limit: postsPerPage,
        skip: i * postsPerPage,
        numPages,
        currentPage: i + 1,
      },
    })
  })

const tags = result.data.tagsGroup.group
  tags.forEach(tag => {
    createPage({
      path: `/tags/${_.kebabCase(tag.fieldValue)}/`,
      component: path.resolve("./src/templates/tags.js"),
      context: {
        tag: tag.fieldValue,
      },
    })
  })
}
exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}

In the file above, we have one query for getting all the posts and then create pages to display them in groups with the postRemark query below:

postRemark: allMarkdownRemark(
  sort: { fields: [frontmatter___date], order: DESC }
    limit: 1000
  ) {
  edges {
    node {
      fields {
        slug
      }
  }
}

We create the page files with:

const posts = result.data.postRemark.edges
  const postsPerPage = 5
  const numPages = Math.ceil(posts.length / postsPerPage)
  Array.from({ length: numPages }).forEach((_, i) => {
    createPage({
      path: `/blog/page/${i + 1}`,
      component: path.resolve("./src/templates/blog-list-template.js"),
      context: {
        limit: postsPerPage,
        skip: i * postsPerPage,
        numPages,
        currentPage: i + 1,
      },
    })
  })

It looks through the returned results and them pipes the resulting entry to the template to generate the pages during build time.

The tagsGroup query below:

tagsGroup: allMarkdownRemark(limit: 2000) {
    group(field: frontmatter___tags) {
      fieldValue
    }
}

Gets all the tags and then pipes the tags into the tags.js template, where it gets the page content and creates the pages during build time with posts for a given tag on each page.

Now we are ready to build the static website by running gatsby build. The files should be built in the public folder.

After that, we install an HTTP server for serving the built static files. We will install the http-server Node.js packages. Run npm i -g http-server. Then, run http-server /path/to/gatsby-blog/public.

After all that is done, we get: