首页 > 解决方案 > 为什么我的状态没有在 setInterval 和 useEffect 的函数内部重置

问题描述

代码:

import React, { useState, useEffect } from 'react';

export default function App() {
  const [isLoading, setLoading] = useState(true);

  const [data, setData] = useState([]);

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

  useEffect(() => {
    const inter = setInterval(() => getData(), 1000);
  }, []);

  async function getData() {
    if (!isLoading) {
      return;
    }

    console.log(isLoading);
    const data = await fetch('http://localhost:8000/api/todo/')
      .then((res) => res.json())
      .then((data) => data);

    if (Array.isArray(data)) {
      setData(data);
      setLoading(false);
    }
  }

  const tododata = data.map((ddd) => {
    return <h1>{ddd.title}</h1>;
  });

  if (isLoading) {
    return <h1>Loading</h1>;
  } else {
    return (
      <>
        {console.log(isLoading)}
        {tododata}
      </>
    );
  }
}

代码摘要

这是我真实项目的简化代码。所以我有 2 个useState,第一个运行一次并尝试第一次获取数据,第二个的目的是如果第一个没有获取数据并且用户卡在加载第二个将反复尝试获取数据,如果前端获取数据,它应该停止获取

我的问题

在这段代码中,getData函数会以某种方式继续获取,指示isLoadingis 为真,但同时组件将从data指示 isLoading 为假的状态呈现所有标题。为什么会这样?

标签: javascriptreactjs

解决方案


我改变我的答案以适应setTimeout而不是setInterval

import React, { useState, useEffect } from 'react';

export default function App() {
  const [isLoading, setLoading] = useState(true);

  const [data, setData] = useState([]);

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

  async function getData() {
    if (!isLoading) {
      return;
    }

    console.log(isLoading);
    try {
      const data = await fetch('http://localhost:8000/api/todo/').then((res) => res.json());

      if (Array.isArray(data)) {
        setData(data);
        setLoading(false);
      } else {
        setTimeout(() => {
          getData();
        }, 1000);
      }
    } catch (e) {
      setTimeout(() => {
        getData();
      }, 1000);
    }
  }

  const tododata = data.map((ddd) => {
    return <h1>{ddd.title}</h1>;
  });

  if (isLoading) {
    return <h1>Loading</h1>;
  } else {
    return (
      <>
        {console.log(isLoading)}
        {tododata}
      </>
    );
  }
}

推荐阅读