typescript 使用React useEffect加载集合失败

ax6ht2ek  于 2023-02-10  发布在  TypeScript
关注(0)|答案(1)|浏览(114)

我试图在从API获取数据时显示一个加载微调器,并在使用useEffect完成后显示错误或结果。由于某种原因,isLoading在获取完成前被设置为false。
你能告诉我到底出了什么问题吗?

const ProblemTable: React.FC<IProblemTableProps> = (props) => {
    // List of problems to show on the table
    const [problems, setProblems] = useState<IProblem[]>([]);

    const [isLoading, setIsLoading] = useState<boolean>(true);
    const [error, setError] = useState<Error>();

    useEffect(() => {
            TierService.getProblems(props.tier, setProblems, setError);
    }, []);

    useEffect(() => {
        setIsLoading(false);
    }, [problems, error]);

    if (isLoading) {
        return <Loading message="Loading problems..." />;
    }

    if (error) {
        return <ErrorMessage title="Failed fetching problems" />;
    }

        return <>...</>;
c3frrgcw

c3frrgcw1#

在组件装载时调用将加载设置为falseuseEffect。添加一个条件,仅在API调用结束时将加载设置为false
例如,如果出现任何问题或错误,请将加载设置为false

useEffect(() => {
    if(problems.length || error) setIsLoading(false);
}, [problems, error]);

但是,如果没有问题或错误,loading将保持true,因此您可能需要一个更严格的条件。更好的方法是,如果调用了任何回调函数,则将loading设置为false

useEffect(() => {
  TierService.getProblems(
    props.tier,
    p => {
      setProblems(p);
      setLoading(false);
    }
    e => { 
      setError(e);
      setLoading(false);
    }
  );
}, []);

根据TierService.getProblems的实现,如果在响应为空时没有调用回调,则第二个建议将失败。
我可能会创建一个基于Promise的API,它允许您将async/awaittry/catch/finally一起使用:

useEffect(() => {
  const api = async () => {
    try {
      const problems = await TierService.getProblems(props.tier);
      setProblems(problems);
    } catch (e) {
      setError(e);
    } finally {
      setLoading(false);
    }
  };

  api();
}, []);

相关问题