How to Use Google Charts in React
Tags: react, javascript, tutorial, beginners
Published: 2021-09-13 08:09:52

---
title: How to Use Google Charts in React
published: true
date: 2021-09-13 07:10:56 UTC
tags: React,Javascript,tutorial,beginner
canonical_url: https://blog.shahednasser.com/how-to-use-google-charts-in-react/
cover_image: https://blog.shahednasser.com/static/5385eed3bb88c35f9384be4c0f1e2e0f/lukas-blazek-mcSDtbWXUZU-unsplash-2-1.jpg
---

_This article was originally published on [my personal blog](https://blog.shahednasser.com/how-to-use-google-charts-in-react/)_

[Google Charts](https://developers.google.com/chart) is a free Javascript library that allows you to visualize data in many types of charts and graphs. It's very useful and easy to use in your projects.

In this tutorial, we'll see how to use Google Charts in React by creating a simple React app with [Create React App](https://create-react-app.dev) (CRA). We'll learn how to use Google Charts with either hooks or context for different use cases.

You can check the code for this tutorial on [this GitHub Repository](https://github.com/shahednasser/react-google-charts-tutorial).

## Create React App

We'll start by creating the React app. Run the following command:

```
npx create-react-app react-google-charts
```

After the command is done, we'll have a react website created with CRA.

We'll also install [react-bootstrap](https://react-bootstrap.github.io) to use some helpful Bootstrap components:

```
npm install react-bootstrap@next bootstrap@5.1.0
```

## Using Google Charts With Hooks

The first approach we'll check is how to use Google Charts in React with Hooks. The code for this section of the tutorial in the GitHub Repository is under `src/WithHooks`.

### Creating the Hook

Create the file `src/useGoogleCharts.js` with the following content:

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

function useGoogleCharts () {
  const [google, setGoogle] = useState(null);
    
    useEffect(() => {
        if (!google) {
            //TODO load google charts
        }
   }, [google]);

  return google;
}

export default useGoogleCharts;
```

This creates a new hook that has a state `google`. This state allows us to check if Google Charts is loaded or not and it will hold the loaded `window.google` object. Then, we will use `useEffect` to load the charts when they're not loaded. Finally, we just return `google`.

In order to load Google Charts, we need to load the script `https://www.gstatic.com/charts/loader.js` in the `<head>` of the document, then when it's loaded, we'll load the core package of Google charts. Finally, when the core package is loaded, we'll set `google` to `window.google`.

Add the following code inside the `if` condition:

```
const head = document.head;
let script = document.getElementById('googleChartsScript');
if (!script) {
    script = document.createElement('script');
    script.src = 'https://www.gstatic.com/charts/loader.js';
    script.id = 'googleChartsScript';
    script.onload = () => {
        if (window.google && window.google.charts) {
            window.google.charts.load('current', {'packages':['corechart']});

            window.google.charts.setOnLoadCallback(() => setGoogle(window.google))
        }
    };
    head.appendChild(script);
} else if (window.google && window.google.charts && window.google.visualization) {
    setGoogle(window.google);
}
```

We're first checking if the script is already loaded to avoid loading it again.

If the script isn't loaded, we're creating the `script` element, and we're adding an event listener for `onload` that will load the code packages of Google Charts.

Then, when the packages are loaded we can set `google` with `setGoogle(window.google)`.

In case the script has already been loaded, we check if `window.google` is set then set `google`.

Finally, we'll return in `useEffect` the following function:

```
return () => {
      let script = document.getElementById('googleChartsScript');
      if (script) {
        script.remove();
      }
    }
```

This removes the script on unmount.

### Creating the Chart Component

Next, we'll create the chart component that will draw the chart after the Google Chart library has been loaded.

Create the component `src/PizzaChart.js` with the following content:

```
import { useEffect, useState } from "react";
import { Spinner } from "react-bootstrap";

function PizzaChart ({google}) {
  const [chart, setChart] = useState(null);
    
  useEffect(() => {
    if (google && !chart) {
        //TODO draw the chart
    }
  }, [loaded, chart]);

  return (
    <>
      {!google && <Spinner />}
      <div id="pizzaChart" className={!google ? 'd-none' : ''} />
    </>
  )
}

export default PizzaChart;
```

This component receives a `google` prop, which will be the returned value from `useGoogleCharts`. It has a `chart` state to ensure that the chart is created only once.

Inside `useEffect`, we'll check if `google` is not null and if `chart` is null. In that case, we'll draw the chart.

Finally, we're just showing a spinner if `google` is null and we're creating the `div` element that the chart will go into.

Back to the if condition in `useEffect`, we need to add the code to draw the chart. We'll add the code from the [Google Charts' Pie Chart Example](https://developers.google.com/chart/interactive/docs/quick_start):

```
// Create the data table.
const data = new google.visualization.DataTable();
data.addColumn('string', 'Topping');
data.addColumn('number', 'Slices');
data.addRows([
    ['Mushrooms', 3],
    ['Onions', 1],
    ['Olives', 1],
    ['Zucchini', 1],
    ['Pepperoni', 2]
]);

// Set chart options
var options = {'title':'How Much Pizza I Ate Last Night',
               'width':400,
               'height':300};

// Instantiate and draw our chart, passing in some options.
const newChart = new google.visualization.PieChart(document.getElementById('pizzaChart'));
newChart.draw(data, options);

setChart(newChart);
```

We're first collecting the data with the options, then we're using `google.visualization` to draw the pie chart. Finally, we set the `chart` state.

Inside `src/App.js`, replace the content with the following:

```
import { Container } from "react-bootstrap";
import PizzaChart from "./PizzaChart";
import useGoogleCharts from './useGoogleCharts';

function App() {
  const google = useGoogleCharts();

  return (
    <>
      <Container className="mt-3">
        <h1>With Hooks</h1>
        <PizzaChart google={google} />
      </Container>
    </>
  );
}

export default App;

```

Try running the server now if it isn't running. You'll see a pie chart.

![How to Use Google Charts in React](https://backend.shahednasser.com/content/images/2021/09/Screen-Shot-2021-09-10-at-3.11.28-PM.png)

### Multiple Charts

Let's try adding another chart. We'll create a new chart component `src/DinosaurChart` with the following content:

```
import { useEffect, useState } from "react";
import { Spinner } from "react-bootstrap";

function DinosaurChart ({google}) {
  const [chart, setChart] = useState(null);

  useEffect(() => {
    if (google && !chart) {
      const data = google.visualization.arrayToDataTable([
        ['Dinosaur', 'Length'],
        ['Acrocanthosaurus (top-spined lizard)', 12.2],
        ['Albertosaurus (Alberta lizard)', 9.1],
        ['Allosaurus (other lizard)', 12.2],
        ['Apatosaurus (deceptive lizard)', 22.9],
        ['Archaeopteryx (ancient wing)', 0.9],
        ['Argentinosaurus (Argentina lizard)', 36.6],
        ['Baryonyx (heavy claws)', 9.1],
        ['Brachiosaurus (arm lizard)', 30.5],
        ['Ceratosaurus (horned lizard)', 6.1],
        ['Coelophysis (hollow form)', 2.7],
        ['Compsognathus (elegant jaw)', 0.9],
        ['Deinonychus (terrible claw)', 2.7],
        ['Diplodocus (double beam)', 27.1],
        ['Dromicelomimus (emu mimic)', 3.4],
        ['Gallimimus (fowl mimic)', 5.5],
        ['Mamenchisaurus (Mamenchi lizard)', 21.0],
        ['Megalosaurus (big lizard)', 7.9],
        ['Microvenator (small hunter)', 1.2],
        ['Ornithomimus (bird mimic)', 4.6],
        ['Oviraptor (egg robber)', 1.5],
        ['Plateosaurus (flat lizard)', 7.9],
        ['Sauronithoides (narrow-clawed lizard)', 2.0],
        ['Seismosaurus (tremor lizard)', 45.7],
        ['Spinosaurus (spiny lizard)', 12.2],
        ['Supersaurus (super lizard)', 30.5],
        ['Tyrannosaurus (tyrant lizard)', 15.2],
        ['Ultrasaurus (ultra lizard)', 30.5],
        ['Velociraptor (swift robber)', 1.8]]);

      var options = {
        title: 'Lengths of dinosaurs, in meters',
        legend: { position: 'none' },
      };

      // Instantiate and draw our chart, passing in some options.
      const newChart = new google.visualization.Histogram(document.getElementById('dinosaurChart'));
      newChart.draw(data, options);

      setChart(newChart);
    }
  }, [google, chart]);

  return (
    <>
      {!google && <Spinner />}
      <div id="dinosaurChart" className={!google ? 'd-none' : ''} />
    </>
  )
}

export default DinosaurChart;
```

This chart component is exactly similar to `PizzaChart`, except it draws a Histogram rather than a Pie Chart. The code for the data is taken from Google Charts' Histogram Example.

Now, add the new component after `PizzaChart` in `src/App.js` in the returned JSX:

```
<PizzaChart google={google} />
<DinosaurChart google={google} />
```

If you open the page now, you'll see two charts.

![How to Use Google Charts in React](https://backend.shahednasser.com/content/images/2021/09/Screen-Shot-2021-09-10-at-3.39.38-PM.png)

## Using Google Charts With Context

You can also use Google Charts with React Contexts. This allows you to use the `google` object in any component without having to call the hook in one component and pass the `google` object as a prop to the chart components.

The code for this section is found in the GitHub Repository in the directory `src/WithContext`.

### Create Google Context

First, create `src/GoogleContext.js` with the following content:

```
import React from "react";

export default React.createContext({
  google: null,
  setGoogle: () => {}
});
```

This will create the Google Context with the `google` object, initially null, and a setter function `setGoogle`.

### Use Context Provider

Inside `src/App.js`, change the content to the following:

```
import { useEffect, useState } from "react";
import { Container } from "react-bootstrap";
import GoogleContext from "./GoogleContext";

function App() {
  const [google, setGoogle] = useState(null);

  useEffect(() => {
    if (!google) {
      const head = document.head;
      let script = document.getElementById('googleChartsScript');
      if (!script) {
        script = document.createElement('script');
        script.src = 'https://www.gstatic.com/charts/loader.js';
        script.id = 'googleChartsScript';
        script.onload = () => {
          if (window.google && window.google.charts) {
            window.google.charts.load('current', {'packages':['corechart']});
            
            window.google.charts.setOnLoadCallback(() => setGoogle(window.google))
          }
        };
        head.appendChild(script);
      } else if (window.google) {
        setGoogle(window.google);
      }
    }

    return () => {
      let script = document.getElementById('googleChartsScript');
      if (script) {
        script.remove();
      }
    }
  }, [google]);

  return (
    <GoogleContext.Provider value={{google, setGoogle}}>
      <Container className="mt-3">
        <h1>With Context</h1>
      </Container>
    </GoogleContext.Provider>
  );
}

export default App;
```

Here, we are creating a `google` state. Then, in `useEffect` we are executing the same code that we did previously in `useGoogleChart`. We are loading the script then setting the `google` state when it's loaded.

Finally, we are surrounding the rendered components with the context provider, passing it the state and its setter as the value.

### Create Chart Component

Next, we'll create the chart component `src/PizzaChart.js` with the following content:

```
import { useContext, useEffect, useState } from "react";
import { Spinner } from "react-bootstrap";
import GoogleContext from "./GoogleContext";

function PizzaChart () {
  const [chart, setChart] = useState(null);
  const { google } = useContext(GoogleContext);

  useEffect(() => {
    if (google && !chart) {
      // Create the data table.
      var data = new window.google.visualization.DataTable();
      data.addColumn('string', 'Topping');
      data.addColumn('number', 'Slices');
      data.addRows([
        ['Mushrooms', 3],
        ['Onions', 1],
        ['Olives', 1],
        ['Zucchini', 1],
        ['Pepperoni', 2]
      ]);

      // Set chart options
      var options = {'title':'How Much Pizza I Ate Last Night',
                    'width':400,
                    'height':300};

      // Instantiate and draw our chart, passing in some options.
      const newChart = new window.google.visualization.PieChart(document.getElementById('pizzaChart'));
      newChart.draw(data, options);

      setChart(newChart);
    }
  }, [google, chart]);

  return (
    <>
      {!google && <Spinner />}
      <div id="pizzaChart" className={!google ? 'd-none' : ''} />
    </>
  )
}

export default PizzaChart;
```

This chart component is similar to the previous chart component we created in the previous section.

First, we are creating the state `chart` to only render the chart once. Then, we're retrieving the context using `useContext`. After that, we're drawing the chart inside `useEffect`. Finally, we're rendering a spinner if google is not loaded, and a `div` element that the chart will be drawn in.

Now, add the component inside the returned JSX in `src/App.js`:

```
<GoogleContext.Provider value={{google, setGoogle}}>
      <Container className="mt-3">
        <h1>With Context</h1>
        <PizzaChart />
      </Container>
    </GoogleContext.Provider>
```

If you open the website now, you'll see the same Pizza Chart we saw when using hooks.

### Multiple Charts

We'll create another chart component `src/DinosaurChart.js` with the following content:

```
import { useContext, useEffect, useState } from "react";
import { Spinner } from "react-bootstrap";
import GoogleContext from "./GoogleContext";

function DinosaurChart () {
  const [chart, setChart] = useState(null);
  const { google } = useContext(GoogleContext);

  useEffect(() => {
    if (google && !chart) {
      const data = google.visualization.arrayToDataTable([
        ['Dinosaur', 'Length'],
        ['Acrocanthosaurus (top-spined lizard)', 12.2],
        ['Albertosaurus (Alberta lizard)', 9.1],
        ['Allosaurus (other lizard)', 12.2],
        ['Apatosaurus (deceptive lizard)', 22.9],
        ['Archaeopteryx (ancient wing)', 0.9],
        ['Argentinosaurus (Argentina lizard)', 36.6],
        ['Baryonyx (heavy claws)', 9.1],
        ['Brachiosaurus (arm lizard)', 30.5],
        ['Ceratosaurus (horned lizard)', 6.1],
        ['Coelophysis (hollow form)', 2.7],
        ['Compsognathus (elegant jaw)', 0.9],
        ['Deinonychus (terrible claw)', 2.7],
        ['Diplodocus (double beam)', 27.1],
        ['Dromicelomimus (emu mimic)', 3.4],
        ['Gallimimus (fowl mimic)', 5.5],
        ['Mamenchisaurus (Mamenchi lizard)', 21.0],
        ['Megalosaurus (big lizard)', 7.9],
        ['Microvenator (small hunter)', 1.2],
        ['Ornithomimus (bird mimic)', 4.6],
        ['Oviraptor (egg robber)', 1.5],
        ['Plateosaurus (flat lizard)', 7.9],
        ['Sauronithoides (narrow-clawed lizard)', 2.0],
        ['Seismosaurus (tremor lizard)', 45.7],
        ['Spinosaurus (spiny lizard)', 12.2],
        ['Supersaurus (super lizard)', 30.5],
        ['Tyrannosaurus (tyrant lizard)', 15.2],
        ['Ultrasaurus (ultra lizard)', 30.5],
        ['Velociraptor (swift robber)', 1.8]]);

      var options = {
        title: 'Lengths of dinosaurs, in meters',
        legend: { position: 'none' },
      };

      const newChart = new google.visualization.Histogram(document.getElementById('dinosaurChart'));
      newChart.draw(data, options);

      setChart(newChart);
    }
  }, [google, chart]);

  return (
    <>
      {!google && <Spinner />}
      <div id="dinosaurChart" className={!google ? 'd-none' : ''} />
    </>
  )
}

export default DinosaurChart;
```

The code is very similar to `PizzaChart` but the data that is being drawn is different, and a Histogram is being drawn instead of a PieChart.

Finally, we need to add the `DinosaurChart` component in the returned JSX in `src/App.js`:

```
return (
    <GoogleContext.Provider value={{google, setGoogle}}>
      <Container className="mt-3">
        <h1>With Context</h1>
        <PizzaChart />
        <DinosaurChart />
      </Container>
    </GoogleContext.Provider>
  );
```

If you open the website now, you'll see the 2 charts.

## Should You Use Context or Hooks?

The approach you use depends on your use case. If you're using one or multiple charts inside the same component, even if as child components, the hook approach can work fine.

However, if you're using multiple charts spread in different components, the best approach would be to use the context.

## Conclusion

In this tutorial, we learned how to use Google Charts with React. The implementation can be expanded if necessary based on your use case, as Google Charts have a lot of use cases and packages other than the core packages.

Make sure to check out [Google Chart's documentation](https://developers.google.com/chart) as well for more information.