UI Is Not Re-Rendering After State is Set in React Hook

Viewed 38

I'm trying to understand state and its relationship with hooks (specifically, the UseEffect hook) and it did not take long to get myself into trouble.

In this small example, I aim to render a list (or projects) with simply an id and a name.

I created a simple hook called useProjects, which uses the fetch API to read in an array of objects from a json file that I dropped in the public directory.

useProjects.js

import { useState, useEffect } from "react";

const useProjects = () => {
  const [projects, setProjects] = useState([]);

  useEffect(() => {
    const fetchProjects = async () => {
      const response = await fetch("./projects.json");
      const projects = await response.json();
      setProjects(projects);
    };
    fetchProjects();
  }, []);

  return { projects };
};

export default useProjects;

This gets used in a very simple function component called ProjectsList:

projectsList.js

import useProjects from "../hooks/useProjects";

const ProjectsList = () => {
  const { projects } = useProjects();

  return (
    <>
      <div>
        <table>
          <thead>
            <tr>
              <th>Id</th>
              <th>Name</th>
            </tr>
          </thead>
          <tbody>
            {projects.length > 0 ? (
              projects.map((h) => (
                <tr key={h.id}>
                  <td></td>
                  <td>{h.name}</td>
                </tr>
              ))
            ) : (
              <tr>
                <td>hi</td>
                <td></td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </>
  );
};

export default ProjectsList;

It does seem to be setting the state (as confirmed in the React dev tools). But there's nothing updating the UI. It just renders the original row which is rendered when the projects array is empty, before it gets populated from the fetch.

What am I missing/doing wrong in terms of having the component re-render when the fetch completes?

Thanks

1 Answers

The fetch never completes, if you log the projects variable inside fetchProducts function, you will see its not getting the data from projects.json. Fix it and you'll be good to go.

Related