Categories
JavaScript React

React Hooks Equivalent of componentDidMount

When we transition from creating class component to function component, one of things we have to do is find the hook equivalents of the life cycle hooks in class components.

One of the life cycle methods that are used a lot is the componentDidMount method.

It loads when the component is first mounted.

To do the same thing in function components, we use the useEffect hook with an empty array in the 2nd argument.

This lets us commit side effects once when the component first loads.

To use it, we write:

import React, { useEffect, useState } from "react";

export default function App() {
  const [data, setData] = useState({});

  const getData = async () => {
    const res = await fetch("https://api.agify.io/?name=michael");
    const data = await res.json();
    setData(data);
  };

  useEffect(() => {
    getData();
  }, []);

  return <div>{data.name}</div>;
}

We reference the useEffect hook with a callback that calls the getData function.

getData just makes a GET request to an API and get some data. Then it set it as the value of the data state.

The empty array indicates that the callback only loads once when the component first loads.

This is because the array has the values to watch for, and we watch nothing, so it only loads once.

Then we return the data we want to display.

We can have more than one reference to useEffect unlike componentDidMount, so we don’t have to put everything in one callback.

Instead, we can have multiple instances of useEffect with empty arrays as the 2nd argument.

App just loads the data on first load and displays it.

Categories
JavaScript React

Reactjs Table Component – React Table

React Table is a simple table component that we can use to create tables in React.

It comes with a good hooks API to make using it easy in function components.

We can start using it by install it:

npm install react-table

Once we did that, we can use it as follows:

import React from "react";
import { useTable } from "react-table";

const data = [
  { id: 1, firstName: "jane", lastName: "doe" },
  { id: 2, firstName: "joe", lastName: "smith" },
  { id: 3, firstName: "may", lastName: "jones" }
];

const columns = [
  {
    Header: "first name",
    accessor: "firstName"
  },
  {
    Header: "last name",
    accessor: "lastName"
  }
];

export default function App() {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow
  } = useTable({ columns, data });

  return (
    <div>
      <table {...getTableProps()}>
        <thead>
          {headerGroups.map(headerGroup => (
            <tr {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map(column => (
                <th {...column.getHeaderProps()}>{column.render("Header")}</th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          {rows.map(row => {
            prepareRow(row);
            return (
              <tr {...row.getRowProps()}>
                {row.cells.map(cell => {
                  return (
                    <td {...cell.getCellProps()}>{cell.render("Cell")}</td>
                  );
                })}
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

We use the useTable hook, which takes an object with columns and data arrays which are in the format that we have on the top of the file.

The hook returns the getTableProps, getTableBodyProps, headerGroups, rows, prepareRow which we use in our table.

We just call and use them in the places that we have above to that we can get the rows and headings displayed.

row.cells have the row entries.

getTableBodyProps return the props for the tbody element.

headerGroups have the header data which we can use to create the table headers from the columns array.

Then we’ll see that we have a table with first name and last name columns with the corresponding names displayed.

Now we create a table without going through the effort of writing out all the code ourselves.

Categories
JavaScript React

Reactjs Table Example

To make a table with React, we just need to use the table element as we do with regular HTML.

Then we use the table, thead, tbody, tr and th elements as follows:

import React from "react";

const data = [
  { id: 1, firstName: "jane", lastName: "doe" },
  { id: 2, firstName: "joe", lastName: "smith" },
  { id: 3, firstName: "may", lastName: "jones" }
];

export default function App() {
  return (
    <div>
      <table>
        <thead>
          <tr>
            <th>first name</th>
            <th>last name</th>
          </tr>
        </thead>
        <tbody>
          {data.map(d => (
            <tr key={d.id}>
              <td>{d.firstName}</td>
              <td>{d.lastName}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

We have the data array, which we map to table rows in between the tbody tags.

The thead has the table headings with the tr for the rows and th for the table headings.

The entries in data are mapped to tr elements with td for the cells.

Then we would get a table with the fields we have in the objects.

Now we have a table with dynamic data in it.

Categories
JavaScript React

Add an Enhanced img Element with react-image – an Example

The React img is just like the HTML version. It’s static and loads images synchronously.

Also, there’s no easy way to add fallback images or handle broken images, and there’s no way to lazy load images.

The react-image package provides all that in one easy to use package.

In this article, we’ll look at how to use react-image with some examples.

To use it, we first install it by running:

npm install react-image --save

Then we can use it by writing the following code:

import React from "react";
import Img from "react-image";

export default function App() {
  return (
    <div className="App">
      <Img src="https://images.unsplash.com/photo-1490750967868-88aa4486c946?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80" />
    </div>
  );
}

The most basic way to use it is just like a regular HTML img element.

We just add the component and pass in the URL of the image to the src prop.

To add a fallback image, we can pass in an array of images, where the ones other than the first one are fallback images.

For instance, we can write:

import React from "react";
import Img from "react-image";

export default function App() {
  return (
    <div className="App">
      <Img
        src={[
          "https://images.unsplash.com/photo-1490750967868-88aa4486c946?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80",
          "https://images.unsplash.com/photo-1494271823928-a80211877d80?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80"
        ]}
      />
    </div>
  );
}

The second URL in the array in the src prop value would be the URL for the fallback image.

It takes a decode prop to prevent flashing before the image is loaded.

We can set decode to false to prevent the flash when it’s loading:

import React from "react";
import Img from "react-image";

export default function App() {
  return (
    <div className="App">
      <Img
        src={[
          "https://images.unsplash.com/photo-1490750967868-88aa4486c946?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80",
          "https://images.unsplash.com/photo-1494271823928-a80211877d80?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80"
        ]}
        decode={false}
      />
    </div>
  );
}

If we load an image restricted with a CORS policy, we can set the crossorigin prop to 'anonymous'.

The loader prop takes a React component to show when an image is loading.

We can write:

import React from "react";
import Img from "react-image";

export default function App() {
  return (
    <div className="App">
      <Img
        src="https://images.unsplash.com/photo-1490750967868-88aa4486c946?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80"
        loader={<p>Loading</p>}
        decode={false}
      />
    </div>
  );
}

To add lazy loading, we can use the VisibilitySensor component that’s built into the react-visibility-sensor package.

We can write:

import React from "react";
import Img from "react-image";
import VisibilitySensor from "react-visibility-sensor";

export default function App() {
  return (
    <div className="App">
      <VisibilitySensor>
        <Img src="https://images.unsplash.com/photo-1490750967868-88aa4486c946?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80" />
      </VisibilitySensor>
    </div>
  );
}

to load the image only when it’s visible on the screen.

The react-visibility-sensor package is separate from react-image, so we have to run:

npm i react-visibility-sensor

to install it.

It’s easy to use react-image to add an enhanced HTML img element. As we can see from the examples, it’s just a matter of passing in a few props to use the enhanced features.

Also, we can use the react-visibility-sensor component to add lazy loading.

Categories
Chart.js JavaScript React

Create a Line Chart with react-chartjs-2 – an Example

react-chartjs-2 is an easy to use library for creating all kinds of charts.

It’s based on Chart.js, which renders chart in an HTML canvas element.

We can use it to render charts in a canvas inside a React app.

To get started, we install Chart.js and react-chartjs-2 by running:

npm install --save react-chartjs-2 chart.js moment

We also installed moments to create dates for the x-axis labels.

Then we can write the following code:

import React from "react";
import { Line } from "react-chartjs-2";
import moment from "moment";

const startDate = new Date(2020, 0, 1);
const labels = [];
for (let i = 0; i < 6; i++) {
  const date = moment(startDate)
    .add(i, "days")
    .format("YYYY-MM-DD");
  labels.push(date.toString());
}

const data = canvas => {
  const ctx = canvas.getContext("2d");
  const gradient = ctx.createLinearGradient(0, 0, 100, 0);
  return {
    backgroundColor: gradient,
    labels,
    datasets: [
      {
        label: "# of Votes",
        data: [12, 19, 3, 5, 2, 3],
        borderWidth: 3,
        fill: false,
        borderColor: "green"
      }
    ]
  };
};

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

We first create the x-axis labels and populate them in the labels array/

We did that by using the moment function and call add on it to add 1 day in each iteration of the for loop.

Then we create a data function, which takes the canvas object, which has the canvas element as the parameter.

Then we get the canvas from it and change the items that we want.

The function returns the options for our graph, including the data.

The object we return in data has various options.

It has the labels property to populate the x-axis labels.

backgroundColor has the color for our graph.

datasets has an array with an object with the data and some options for the line.

data has the y-axis values for each x-axis value.

borderWidth specifies the thickness of the line in pixels.

fill is set to false means that we don’t have any colors between the x-axis and our line.

label is the text label for our legend.

borderColor is the color of our line.

Once we have that code, we’ll see the following graph:

https://thewebdev.info/wp-content/uploads/2020/05/react-chartjs-2.png