1

Like the title says useFetch custom hook that I made is returning data twice, what do I mean by that. Well when I console.log the data that I fetched there are two outputs, one of them has value null, and the other is the data that I want, and because there is data with null value, that is a problem since I can't fulfill the table with the data I want. Here is the code:

import { useState, useEffect } from "react";
import axios from "axios";
const useFetch = (url) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading(true);
    axios
      .get(url)
      .then((response) => {
        setData(response.data);
      })
      .catch((err) => {
        setError(err);
      })
      .finally(() => {
        setLoading(false);
      });
  }, [url]);

  return { data, loading, error };
};

export default useFetch;

And this is where I want to use the data I fetched:

import React from "react";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import useFetch from "./custom_hooks/useFetch";

const TableComponent = () => {
  const { data, loading, error } = useFetch(
    "https://gorest.co.in/public/v1/users?page=1"
  );

  if (loading) return <h1> LOADING...</h1>;

  if (error) console.log(error);

  console.log(data);

  return (
    <TableContainer>
      <Table>
        <TableHead>
          <TableRow>
            <TableCell>User Names</TableCell>
            <TableCell align="right">Email</TableCell>
            <TableCell align="right">Status</TableCell>
            <TableCell align="right">Gender</TableCell>
            <TableCell align="right">ID</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {data.data.map((user) => {
            return (
              <TableRow>
                <TableCell>{user.name}</TableCell>
              </TableRow>
            );
          })}
        </TableBody>
      </Table>
    </TableContainer>
  );
};

export default TableComponent;

When I refresh the page, there is an error 'Data is null', how to fix this?

2
  • 1
    can you add the logs to the description of you question , Commented Oct 4, 2021 at 12:20
  • 1
    Well, that's to be expected, no? You initialize data in useFetch hook as null. Then, when your TableComponent is first rendered, the useEffect inside useFetch fires, at which point the data is (asynchronously) loaded. When the data is loaded, your TableComponent sees there is new data available, and thus re-renders itself. This is how React works. Either initialize your data with something other than null, or just check if data !== null before trying to render it. Commented Oct 4, 2021 at 12:20

1 Answer 1

3

Your hook doesn't manage its internal state quite properly. (For instance, if a fetch errors, it never un-errors.) Also, if you change the URL, the hook could end up having data for the wrong URL due to a previous effect finishing first.

As such, maybe it'd be better to just look at whether you do have data instead of trusting the other flags to be correct:

const { data, loading, error } = useFetch("https://gorest.co.in/public/v1/users?page=1");
if(error) return <>Error: {String(error)}</>;
if(!data) return <h1>LOADING...</h1>;

Beyond that, you might want to look into a library that does the state management, caching, etc. correctly for you; at the time of writing I'd recommend swr or react-query...

Sign up to request clarification or add additional context in comments.

1 Comment

This fixed the issue for now, I will now go take a look at react-query, thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.