【发布时间】:2020-08-31 17:26:41
【问题描述】:
我正在努力将 React 组件从类组件转换为带有钩子的功能组件。
我想从我的数据库中获取组成员列表。我将数组保持在组件状态。
const [members, setMembers] = useState([]);
会员下载后,我想异步获取每个会员的头像。
1) 组件被挂载,下面的useEffect()被调用。注意对getMembers 的依赖。
useEffect(() => {
getMembers();
}, [getMembers]);
2) useEffect 回调调用函数getMembers()。注意对getMembersProfilePictures 的依赖。
const getMembers = useCallback(() => {
fetchMembersFromDatabase()
.then((data) => {
setMembers(data);
getMembersProfilePictures();
})
}, [getMembersProfilePictures]);
3) 一旦从数据库中检索到成员,members 状态就会更新并调用getMembersProfilePictures()。注意对members 的依赖。
const getMembersProfilePictures = useCallback(() => {
for (let i = 0; i < members.length; i++) {
const member = { ...members[i] };
if (member.has_picture) {
firebase
.storage()
.ref()
.child("<childUrl>")
.getDownloadURL()
.then((url) => {
member.picture_url = url;
const membersCopy = [...members];
membersCopy[i] = member;
setMembers(membersCopy);
});
}
}
}, [members]);
因为useEffect() 依赖于getMembers(),getMembers() 依赖于getMembersProfilePictures(),而getMembersProfilePictures() 依赖于members,所以一旦members 状态更新,useCallback() 的链s 被重新创建,useEffect() 被调用。这变成了数据获取的无限循环。
我目前的想法是将从fetchMembersFromDatabase() 检索到的数据直接传递给getMembersProfilePictures() 作为参数。这从getMembersProfilePictures() 中移除了members 的依赖关系,从而移除了无限循环。
忽略监听数据库中成员列表的变化,忽略缓存成员及其各自的头像,看来这个解决方案没有缺点。我想知道其他人对此解决方案的想法是什么。谢谢!
【问题讨论】:
-
getMembers和getMembersProfilePictures是同一个回调的一部分,您不必要地将它们分开并创建了一个依赖循环。 -
@Adam 分开是什么意思?这两个功能是否应该合并为一个功能?如果是这样的话,我相信我仍然会有一个依赖循环。
-
不会,因为
getMembersProfilePictures将不再依赖members,因为members直接来自fetchMembersFromDatabase调用。 -
我有一个更好的解决方案给你——创建一个“会员”组件,让每个会员组件负责下载自己的图片,你的“顶级”组件应该只关心获取列表成员。
-
99% 的开发人员试图从他们的组件中创建迷你应用程序,而不是仅仅创建极小的、几乎愚蠢的小组件。我最喜欢的组件类型是如此之小以至于可笑,例如
OptionalThemeComponent = ({theme,children}) => theme ? <ThemeProvider theme={theme}>{children}</ThemeProvider> : children这就是基于组件的开发应有的样子 - 组件如此之小以至于您可以在 1 分钟内了解它们所做的一切。
标签: javascript reactjs react-hooks