rstowe1
rstowe1

Reputation: 81

Data leak due to using asynchronous function

I am getting a data leak while using an asychronous function causing my application to not load the second page during navigation.

I am using async/await on my get request, and I have tried to use a cleanup function to prevent this leak, but it is not working.

How do I fix this leak, and still get the data to load when the page is loaded?

import React, { useEffect, useState, useContext } from "react";
import ReactTable from "react-table";
import "react-table/react-table.css";
import axios from "axios";
import StatusContext from "../../context/status/statusContext";

const Table = props => {
  const [tableData, setTableData] = useState([]);

  const statusContext = useContext(StatusContext);

  useEffect(async () => {
    await axios
      .get("/api/status")
      .then(function(response) {
        console.log(response.data);
        setTableData(
          response.data.filter(item => {
            let itemDate = new Date(item.date);
            let variableDate = new Date() - 604800000;

            return itemDate > variableDate;
          })
        );
      })
      .catch(function(error) {
        console.log(error);
      });
  }, [statusContext]);

  const columns = [
    {
      id: "Name",
      Header: "Name",
      accessor: "name"
    },
    {
      Header: "Date",
      accessor: "date"
    },
    {
      Header: "Comment",
      accessor: "comment"
    }
  ];

  return (
    <ReactTable
      data={tableData}
      columns={columns}
      pivotBy={["date"]}
      defaultPageSize={7}
      minRows={5}
    />
  );
};

export default Table;

Upvotes: 0

Views: 79

Answers (1)

helloitsjoe
helloitsjoe

Reputation: 6529

There's really no need to bring async/await into this situation, and in fact useEffect won't work if you do. The only thing you can return from useEffect is a cleanup function, and an async function returns a Promise.

This should work just fine, including a cleanup function in case you unmount your component before the promise resolves:


  useEffect(() => {
    let isMounted = true;

    axios
      .get("/api/status")
      .then(function(response) {
        if (!isMounted) {
          return;
        }
        console.log(response.data);
        setTableData(
          response.data.filter(item => {
            let itemDate = new Date(item.date);
            let variableDate = new Date() - 604800000;

            return itemDate > variableDate;
          })
        );
      })
      .catch(function(error) {
        console.log(error);
      });

    return () => {
      isMounted = false;
    }
  }, [statusContext]);

Upvotes: 1

Related Questions