Why use useEffect() hook

Hi all,
I am following along in the NextJS course building the Issue Tracker. I am on the section called "Populate the Assignee dropdown. In the code he is using the useEffect() hook. He does not explain why, just says go back to my React course. So far, this is the only code that uses that hook and would like to know why.

"use client";

import { User } from "@prisma/client";
import { Select } from "@radix-ui/themes";
import axios from "axios";
import React, { useEffect, useState } from "react";

const AssigneeSelect = () => {
  const [users, setUsers] = useState<User[]>([]);

  useEffect(() => {
    const fetchUsers = async () => {
      const { data } = await axios.get<User[]>("/api/users");
      setUsers(data);
    };

    fetchUsers();
  }, []);

  return (
    <Select.Root>
      <Select.Trigger placeholder="Assign..." />
      <Select.Content>
        <Select.Group>
          <Select.Label>Suggestions</Select.Label>
          {users.map((user) => (
            <Select.Item key={user.id} value={user.id}>
              {user.name}
            </Select.Item>
          ))}
        </Select.Group>
      </Select.Content>
    </Select.Root>
  );
};

export default AssigneeSelect;

Initially I thought it was because we were calling back end code to get data when the component is set to “use client”, however, the course has other components that are set to run client side and call back end code and the useEffect() hook is not used:

"use client";

import { AlertDialog, Button, Flex, Spinner } from "@radix-ui/themes";
import axios from "axios";
import { useRouter } from "next/navigation";
import { useState } from "react";

const DeleteIssueButton = ({ issueId }: { issueId: number }) => {
  const router = useRouter();
  const [hasError, setError] = useState(false);
  const [isDeleting, setDeleting] = useState(false);

  const deleteIssue = async () => {
    try {
      setDeleting(true);
      await axios.delete("/api/issues/" + issueId);
      router.push("/issues/list");
      router.refresh(); 
    } catch (error) {
      setError(true);
      setDeleting(false);
    }
  };

  return (
    <> ..... markup here...

Can someone please explain why useEffect is needed in this case and why it would be used in NextJS at all?

Thank you,
Jim

1 Like

UseEffect with an empty array as the second argument is a way of ensuring the code executed happens on the first mount of the component in react. I recommend looking into component lifecycles for react, its done differently with class components vs functional components, and this is how its done for functional components.

In regards to why it’s done the Assignee select component and not in the other component, the difference is that the user data for AssigneeSelect needs to be present before the code in the return of the component is rendered in order to properly map out the Users. But in the DeleteIssueButton, we aren’t collecting any data that the UI requires for rendering. We are making a call to the database to execute an endpoint, thats all. No data that we are needing to store in local state and serve.

Hope this helps!

2 Likes

Thank you very much for your detailed explanation!
I will look into component lifecycle to get more of an understanding.

Thank you again!!

1 Like