首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当fetch中的URL在react中更改时,如何在所有元素的顶部显示加载?

当fetch中的URL在react中更改时,如何在所有元素的顶部显示加载?
EN

Stack Overflow用户
提问于 2022-08-01 06:08:59
回答 1查看 59关注 0票数 1

我有从URL获取json数据的代码,并显示它,如下所示:

代码语言:javascript
复制
  const [error, setError] = useState(null);
  const [isLoaded, setIsLoaded] = useState(false);
  const [items, setItems] = useState([]);
  const [url, setUrl] = useState(url);

  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(
        (result) => {
          setIsLoaded(true);
          setItems(result);
        },
        // Note: it's important to handle errors here instead of a catch() block
        // so that we don't swallow exceptions from actual bugs in components.
        (error) => {
          setIsLoaded(true);
          setError(error);
        }
      )
  }, [url, setUrl]);

  if (error) {
    return <div>Error: {error.message}</div>;
  } else if (!isLoaded) {
    return <LoadingAnimation />;
  } else {
    return <BasicLayout items={items} setUrl={setUrl} />;
  }

其中url只是一个任意的url,它为我获取一些数据。我有一个定制的LoadingAnimation函数,它只在页面未加载时显示加载。我将setUrl传递到BasicLayout函数中,因为我希望通过单击按钮更改BasicLayout参数,并更新数据并显示数据。当触发setUrl时,数据按其应有的方式更新,延迟4-5秒。另外,当数据在4-5秒延迟期间更新时,我希望在所有元素之上显示一个不同的加载动画,并使用户在fetch更新时无法单击任何内容。

我尝试过将setIsLoaded传递到BasicLayout中,但这只是替换了整个屏幕,并重新呈现了每个组件。我特别不想重新呈现任何东西;只是呈现加载图标,并在所有更新完成后隐藏它。我该怎么做?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-01 07:27:39

此时,在您的组件中,if语句return必须呈现什么反应。所以你没有什么办法:

在本例中,如果LoadingAnimation更改反应将显示BasicLayout错误消息,但如果isLoaded将更改,则将隐藏/显示在前面的元素下。

代码语言:javascript
复制
  useEffect(() => {
...
  }, [url, setUrl]);

return (
<>
 {error ? <div>Error: {error.message}</div> : <BasicLayout items={items} setUrl={setUrl} />}
 {!isLoaded && <LoadingAnimation />}
</>
)

如果您要使用正确的css样式,您可以简单地将LoadingAnimation作为一个模式(弹出),但是对于modals,就像我一样,最好使用反应门户

index.html

代码语言:javascript
复制
<div id='root' ></div>
<div id='modal' ></div>

Portal.jsx

代码语言:javascript
复制
const Portal = ({children}) => {
const portalNode = document.getElementById('modal')
  return createPortal(children, portalNode)
}

Modal.jsx

代码语言:javascript
复制
const Modal = ({isActive, setIsActive, children}) => {
return (
<Portal>
{isActive && <div>{/* ...some code with children */}</div>}
</Portal>
)
}

所以在您的组件中,它将是这样的

代码语言:javascript
复制
  useEffect(() => {
...
  }, [url, setUrl]);

return (
<>
{error ? 
<div>Error: {error.message}</div>
 : 
<BasicLayout items={items} setUrl={setUrl} />}
<Modal isActive={!isLoaded} ><LoadingAnimation /></Modal>
</>
)

您也可以建立错误组件模型。

希望,它会有帮助的:)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73189423

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档