1

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

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

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

这是应用程序组件代码,我从 API 获取日期并通过道具传递给用户组件。

// 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
   }, []);

我已经录制了一个视频,所以你们可以很容易地理解我想说什么。 视频链接

检查实时应用

我怎么解决这个问题?

预先感谢!

4

2 回答 2

1

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

  1. App 组件第一次渲染时,状态user={}loading=false
  2. 当您单击用户时,组件会使用 props和User呈现,因此不会显示微调器,也不会显示数据。user={}loading=false
  3. User安装组件后,useEffect触发钩子,getUser调用并设置loading=true(显示微调器)然后我们获取用户数据user=user1并设置loading=false(现在用户数据已呈现)
  4. 当您返回搜索页面时,应用程序状态仍然是user=user1并且loading=false
  5. 现在,当您单击另一个用户时,User组件会使用 propsuser=user1和渲染loading=false,因此不会显示微调器,并且会渲染来自前一个用户的数据。
  6. User安装组件后,useEffect触发钩子,getUser调用并设置loading=true(显示微调器)然后我们获取用户数据user=user2并设置loading=false(现在呈现新的用户数据)

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

  • 而不是对组件使用loading布尔值,而是将其User反转并使用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 />;

你可以在这里找到完整的代码

于 2019-08-22T10:08:21.910 回答
0

请在 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);
  }
于 2019-08-22T09:49:33.680 回答