从 api 获取时反应 useEffect 无限循环

React useEffect Infinite loop when fetching from api

我试图将我的获取请求中的数据存储到一个状态中,但即使没有依赖性,它也会无限循环。当我删除 div 中的代码时,我过滤掉并映射出数组,它似乎不会无限循环,但我不知道为什么 filtering/mapping 会导致它像那样循环

function App() {
  const [searchTerm, setSearchTerm] = useState("");
  const [students, setStudents] = useState([]);
  const [isActive, setIsActive] = useState(false);
  const average = (array) => {
    return array.reduce((a, b) => a + parseFloat(b), 0) / array.length;
  };
  useEffect(() => {
    const api = async () => {
      await fetch("https://api.hatchways.io/assessment/students")
        .then((res) => res.json())
        .then((data) => setStudents(data.students));
    };

    api();
  }, []);
  return (
    <div className='bg-gray-300 h-screen flex items-center justify-center'>
      {students
        .filter((student) => {
          if (searchTerm === "") {
            return student;
          } else if (
            student.firstName
              .toLowerCase()
              .includes(searchTerm.toLowerCase()) ||
            student.lastName.toLowerCase().includes(searchTerm.toLowerCase())
          ) {
            return student;
          }
        })
        .map((student, i) => (
          <div
            key={i}
            className='flex items-center space-x-8 px-8 py-3 border-b'>
            <div className='flex items-start w-full space-x-7'>
              <div className='border overflow-hidden rounded-full'>
                <img
                  className='w-24 h-24 bg-contain'
                  src={student?.pic}
                  alt='student school portrait'
                />
              </div>
              <div className='flex flex-col justify-between space-y-4 w-full'>
                <div className='flex items-center justify-between'>
                  <h1 className='font-bold text-5xl'>
                    {student?.firstName} {student?.lastName}
                  </h1>
                  <button onClick={setIsActive(!isActive)}>
                    {isActive ? (
                      <AiOutlinePlus className='h-7 w-7' />
                    ) : (
                      <AiOutlineMinus className='h-7 w-7' />
                    )}
                  </button>
                </div>
                <div className='pl-3'>
                  <p>Email: {student?.email}</p>
                  <p>Company: {student?.company}</p>
                  <p>Skill: {student?.skill}</p>
                  <p>Average: {average(student?.grades).toFixed(2)}%</p>
                </div>
              </div>
            </div>
          </div>
        ))}
    </div>
  );
}

如果您使用 async/await,则无需链接 .then()。 尝试将您的 useEffect 更新为:

     useEffect(() => {
        api();
      }, []);

        const api = async () => {
             let res = await fetch("https://api.hatchways.io/assessment/students");
             let data = await res.json();
             setStudents(data.students)
        }; 

此外,在按钮单击处理程序中使用箭头函数:

<button onClick={()=>setIsActive(!isActive)}>

尝试使用 async-await 语法

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch(
        "https://api.hatchways.io/assessment/students"
      );
      const result = await response.json();

      console.log("res", result);
    };

    fetchData();
  }, []);

如果要处理错误,需要添加try catch块。

大多数情况下,我尝试在 useEffect 内部调用函数,同时在 useEffect 外部对该函数进行编码。它对我有用,试试看。

 useEffect(() => {
        api();
      }, []);
    
        const api = async () => {
          await fetch("https://api.hatchways.io/assessment/students")
            .then((res) => res.json())
            .then((data) => setStudents(data.students));
        };

问题是在单击按钮时没有设置箭头功能:<button onClick={() => setIsActive(!isActive)}>

<button onClick={setIsActive(!isActive)}> 这可能是罪魁祸首。你正在改变每一个兰德的状态。您应该将 () => setIsActive(!isActive) 作为 onClick 处理程序传递。