首页 > 解决方案 > 如何在反应路由器中加载进入下一个路由之前避免闪烁?

问题描述

我想prepare在进入路线之前准备下一页,此时会显示一个加载页面。

我曾尝试使用useLocationuseEffect但在显示加载页面之前下一页会闪现。

const [loading, setLoading] = useState(true);
const location = useLocation(); // react-router

useEffect(() => {
  setLoading(true);
  setTimeout(() => {
    prepare(() => setLoading(false)); // callback when `prepare` is complete
  }, 0);
}, [location.pathname, prepare, setLoading]);

return (
  <Switch>
    {routes.map((route) => (
      <Route
        key={route.path}
        path={route.path}
        render={() => loading ? '' : <route.component />}
      />
    ))}
  </Switch>
);

目前我正在使用一个肮脏的解决方案DelayedComponent

const DelayedComponent = (props) => {
  const { component } = props;
  const [show, setShow] = useState(false);

  useEffect(() => {
    const timeout = setTimeout(() => {
      setShow(true);
    }, 1000);

    return () => {
      clearTimeout(timeout);
    }
  }, []);

  return show ? createElement(component) : <div />;
};

标签: react-router

解决方案


我不确定,我是否正确理解了您的问题,但我会尝试提出一些建议

这是你的路由器:

<Switch>
  {routes.map(({ path, component: Component }) => (
    <Route
     exact
     key={path}
     path={path}
   >
     <Component />
   </Route>
 ))}
</Switch>

然后你的任何组件

// Users.js
import React from 'react';

import useFetchUsers from './useFetchUsers';

const Users = () => {
  const { isLoadingUsers, users } = useFetchUsers();

  if (isLoadingUsers) {
    return <LoadingWhatEverComponent />
  }

  return (
    <div>{users.map((user) => user.name)}</div>
  )
}

在未加载用户之前,您将显示加载屏幕

// useFetchUsers.js

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

export default () => {
  const [isLoading, setIsLoading] = useState(true);
  const [users, setUsers] = useState([]);

  const fetchUsers = useCallback(async () => {
    try {
      const response = await axios(...);
      setUsers(response.data.users);
    } catch (error) {
      console.error(error);
      setUsers([]);
    } finally {
      setLoading(false);
    }
  }, [])

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

  return {
    isLoadingUsers: isLoading,
    users
  }
}

结果 fetchUsers 还没结束之前,只能看到加载组件


推荐阅读