【问题标题】:React render page after API callAPI调用后反应渲染页面
【发布时间】:2021-04-26 22:18:24
【问题描述】:

当我在我的 React 应用程序的页面之间导航时,每个页面都会出现反弹(这意味着该页面首先呈现没有任何数据 [例如用户名、出生日期、图像],然后几毫秒/秒后出现一些细节在 API 请求完成并更新状态时显示在屏幕上。

例如我有以下页面:

<div className="home" onClick={() => history.push('/')}></div>
<div className="user" onClick={() => history.push('/user')}></div>
<div className="settings" onClick={() => history.push('/settings')}></div>

这导致当我单击“设置”按钮时,我首先转到/settings 路由,然后组件在发出 API 请求时开始重新渲染和弹跳。在每个页面中,我都会发出一个或多个 API 请求来获取数据。我使用useEffect 钩子提出这些请求。例如:

const Settings = () => {
  const [userDetails, setUserDetails] = useState(null);
  const [userImages, setUserImages] = useState([]);

  useEffect(() => {
    const getUserDetails = async () => {
     const response = await getUserSettingsDetails();
     setUserDetails(response.data);
   }
   const getUserImages = async = () => {
     const response = await getUserSettingsImages();
     setUserImages(response.data);
  }
  getUserDetails();
  getUserImages();
  }, []);

  return ( 
     ... 
  );
}

我想要达到的目标:

例如,当我在“主页”上并单击以转到“设置”时,我希望仅在 API 请求完成后导航和呈现设置页面,并且我可以立即在屏幕上显示所有详细信息。我有一个不错的行加载组件,我想在加载时显示在标题中。 (与 YouTube 类似,它在导航时会显示一个红色进度条)。我也在这个项目中使用 Redux,我认为它可以在这里使用,但我不明白如何做到这一点。谁能解释一下如何实现这种行为。

【问题讨论】:

    标签: javascript reactjs redux navigation


    【解决方案1】:

    您好,我认为您可以使用 Promise.all([]) 和加载状态

    const Settings = () => {
     const [userDetails, setUserDetails] = useState(null);
     const [userImages, setUserImages] = useState([]);
     const [loading,setLoading] = useState(false)
    
     const getUsersInfos = async () => {
      try {
       const result = await new Promise.all([
         getUserSettingsDetails(),
         getUserSettingsImages(),
       ])
    
       const details = result[0]
       const images = result[1]
    
       //i'm not sure if we need to test
       if(details.data && images.data){
         setUserDetails(details.data);
         setUserImages(images.data);
         setLoading(true)
       }
    
      } catch (error) {
       console.log(error);
     }
    }
    
    useEffect(() => {
      getUsersInfos();
    }, []);
    
    return ( 
      <>
       {loading && (
         ...
       )}
      </>
     );
    }
    

    【讨论】:

      【解决方案2】:

      虽然我相信@Daphaz 的回答非常好,但我会使用 redux-thunk 或 redux-sagas 采用更好、更简洁的方法。使用 redux,您只能进行简单的同步更新,而在这里您将进行异步更新,因此您需要像我提到的那样的中间件。

      Redux-thunk Redux-sagas

      有大量使用此中间件的示例来实现您正在寻找的目标。

      【讨论】:

        【解决方案3】:

        您可以创建一个名为isLoading 的额外状态,并在开始获取任何数据时将其设置为真。然后,在 await 语句下方,您可以将 isLoading 设置为 false。

        因此,您可以在 JSX 代码中使用 isLoading 状态进行条件渲染,例如,您可以在 isLoading 变量的值为 true 时显示加载组件,然后,当变量为 false 时,根据需要显示您的页面。

        const Settings = () => {
          const [state, setState] = useState({});
          const [isLoading, setIsLoading] = useState(false);
        
          useEffect(() => {
            const getAllInformation = async () => {
              // start loading
              setIsLoading(true);
              // make the request here
              const data = await fetch();
              setState({ ...data });
              // already finished here
              setIsLoading(false);
            };
            getAllInformation()
          }, []);
        
          return (
            <div>
              {isLoading ? (
                <Loading />
              ) : (
                {
                  /* MORE CODE */
                }
              )}
            </div>
          );
        };
        
        

        【讨论】:

          猜你喜欢
          • 2022-01-25
          • 2019-09-09
          • 2020-10-31
          • 2022-10-06
          • 1970-01-01
          • 2020-08-12
          • 2019-01-05
          • 2021-04-23
          • 1970-01-01
          相关资源
          最近更新 更多