组件在挂载几分之一秒时显示以前的数据

Component shows previous data when mount for fractions of seconds

我正在开发一个名为 "GitHub Finder" 的应用程序。

我正在使用异步函数在 App 组件中获取日期,并将这些函数作为 props 传递给 User 组件,我在 useEffect 中调用这些函数。

问题就在这里,当我第二次转到用户页面时,它显示了我从 App 组件传入的 props 的先前数据,然后它显示了加载程序并显示了新数据。

这是 App 组件代码,我在其中从 API 获取日期并通过 props 传递给 User 组件。

// Get single GitHub user
  const getUser = async (username) => {
    setLoading(true);

    const res = await axios.get(
    `https://api.github.com/users/${username}?client_id=${
     process.env.REACT_APP_GITHUB_CLIENT_ID}&client_secret=${
     process.env.REACT_APP_GITHUB_CLIENT_SECRET}`
  );
    setUser(res.data);
    setLoading(false);
  }
  // Get user repos
  const getUserRepos = async (username) => {
    setLoading(true);

    const res = await axios.get(
      `https://api.github.com/users/${username}/repos? 
       per_page=5&sort=created:asc&client_id=${
       process.env.REACT_APP_GITHUB_CLIENT_ID}&client_secret=${
       process.env.REACT_APP_GITHUB_CLIENT_SECRET}`
     );

    setRepos(res.data);    
    setLoading(false);
   }`

用户组件代码.

  useEffect(() => {
        getUser(match.params.login);
        getUserRepos(match.params.login);
    // eslint-disable-next-line
   }, []);

我录制了一段视频,大家可以很容易地理解我想说的意思。 Video link

Check live app

我该如何解决这个问题?

提前致谢!

请像这样在 getUser 的开头让您的 setUser([]) 为空:

  const getUser = async (username) => {
    setLoading(true);
    setUser([]);

    const res = await axios.get(
    `https://api.github.com/users/${username}?client_id=${
     process.env.REACT_APP_GITHUB_CLIENT_ID}&client_secret=${
     process.env.REACT_APP_GITHUB_CLIENT_SECRET}`
  );
    setUser(res.data);
    setLoading(false);
  }

这是应用程序中发生的事情:

  1. 第一次渲染App组件时,状态为user={}loading=false
  2. 当您点击用户时,User 组件会使用属性 user={}loading=false 呈现,因此不会显示微调器,也不会显示任何数据。
  3. 安装 User 组件后,触发 useEffect 钩子,调用 getUser 并设置 loading=true (显示微调器)然后我们得到用户数据 user=user1 并设置 loading=false (现在用户数据已呈现)
  4. 当您返回搜索页面时,应用程序状态仍然是 user=user1loading=false
  5. 现在,当您点击另一个用户时,User 组件会使用道具 user=user1loading=false 进行渲染,因此不会显示微调器,而是会渲染前一个用户的数据。
  6. 安装 User 组件后,触发 useEffect 钩子,调用 getUser 并设置 loading=true (显示微调器)然后我们得到用户数据 user=user2 并设置 loading=false (现在呈现新的用户数据)

解决此问题的一种可能方法:

  • 不要对 User 组件使用 loading 布尔值,而是将其反转并使用 loaded
  • 卸载 User 组件时清除用户数据和加载的布尔值。

应用组件:

 const [userLoaded, setUserLoaded] = useState(false);

 const getUser = async username => {
    await setUserLoaded(false);

    const res = await axios.get(
      `https://api.github.com/users/${username}?client_id=${
        process.env.REACT_APP_GITHUB_CLIENT_ID
      }&client_secret=${process.env.REACT_APP_GITHUB_CLIENT_SECRET}`
    );

    await setUser(res.data);
    setUserLoaded(true);
  };

  const clearUser = () => {
    setUserLoaded(false);
    setUser({});
  };

<User
  {...props}
  getUser={getUser}
  getUserRepos={getUserRepos}
  repos={repos}
  user={user}
  loaded={userLoaded}
  clearUser={clearUser}
/>

用户组件:

  useEffect(() => {
    getUser(match.params.login);
    getUserRepos(match.params.login);
    // eslint-disable-next-line

    return () => clearUser();
  }, []);

  if (!loaded) return <Spinner />;

你可以找到完整的代码here