首页 > 解决方案 > 如何避免 React.js 中的 useEffect 和 useCallback 依赖循环

问题描述

我正在将 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()depends on getMembers(), getMembers()depends on getMembersProfilePictures(), and getMembersProfilePictures()depends on members,一旦members状态更新,useCallback()s 的链就会重新创建,并useEffect()调用 。这成为数据获取的无限循环。

我目前的想法是将检索到的数据fetchMembersFromDatabase()直接传递给getMembersProfilePictures()作为参数。members这消除了from的依赖性getMembersProfilePictures(),因此消除了无限循环。

忽略监听数据库中成员列表的变化并忽略缓存成员和他们各自的个人资料图片,这个解决方案似乎没有缺点。我想知道其他人对此解决方案的想法是什么。谢谢!

标签: javascriptreactjsreact-hooks

解决方案


  • 您正在调用fetchMembersFromDatabase()useCallback不将其用作依赖项。
  • 您正在设置members其中getMembersProfilePictures()使用成员作为依赖项。在我看来,这导致了无限循环。

建议的解决方案

  1. useEffect没有任何依赖
  2. useEffect为成员并调用获取成员图像函数。为成员缩略图维护另一个对象。

推荐阅读