组件在挂载几分之一秒时显示以前的数据
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
我该如何解决这个问题?
提前致谢!
请像这样在 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);
}
这是应用程序中发生的事情:
- 第一次渲染App组件时,状态为
user={}
和loading=false
- 当您点击用户时,
User
组件会使用属性 user={}
和 loading=false
呈现,因此不会显示微调器,也不会显示任何数据。
- 安装
User
组件后,触发 useEffect
钩子,调用 getUser
并设置 loading=true
(显示微调器)然后我们得到用户数据 user=user1
并设置 loading=false
(现在用户数据已呈现)
- 当您返回搜索页面时,应用程序状态仍然是
user=user1
和 loading=false
- 现在,当您点击另一个用户时,
User
组件会使用道具 user=user1
和 loading=false
进行渲染,因此不会显示微调器,而是会渲染前一个用户的数据。
- 安装
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
我正在开发一个名为 "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
我该如何解决这个问题?
提前致谢!
请像这样在 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);
}
这是应用程序中发生的事情:
- 第一次渲染App组件时,状态为
user={}
和loading=false
- 当您点击用户时,
User
组件会使用属性user={}
和loading=false
呈现,因此不会显示微调器,也不会显示任何数据。 - 安装
User
组件后,触发useEffect
钩子,调用getUser
并设置loading=true
(显示微调器)然后我们得到用户数据user=user1
并设置loading=false
(现在用户数据已呈现) - 当您返回搜索页面时,应用程序状态仍然是
user=user1
和loading=false
- 现在,当您点击另一个用户时,
User
组件会使用道具user=user1
和loading=false
进行渲染,因此不会显示微调器,而是会渲染前一个用户的数据。 - 安装
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