【问题标题】:How to use Nested map() functions while fetching data from Firebase Firestore如何在从 Firebase Firestore 获取数据时使用嵌套的 map() 函数
【发布时间】:2019-06-07 15:08:10
【问题描述】:

我正在学习 React,我有一些 menusub_menu 项目,我在 Firestore 上创建了两个不同的集合,并从中获取数据。我想显示菜单并根据他们的父 id 显示他们的子菜单。

我在 ma​​p() 中使用了 JavaScript map(),并且我的代码运行良好,但我想知道我的方法是否正确,因为我在控制台中收到以下警告:

第 35 行:期望在箭头函数 array-callback-return 的末尾返回一个值

我做错了什么?

project_action.jsx(使用 Redux 代码的动作文件)

// FETCHING HEADER MENU ITEMS
export const fetchMenuItems = () => {
    return (dispatch, getState, { getFirebase, getFirestore }) => {
        // MAKE ASYNC CALL
        const firestore = getFirestore();
        let mainData = [];
        let subMenuData = [];
        // GETTING MAIN MENUES
        firestore.collection('header_menu_items').orderBy('item_pos', 'asc').get().then(querySnapshot => {
            querySnapshot.forEach(doc => {
                mainData.push({
                    item_id: doc.id,
                    item_name: doc.data().item_name,
                    item_link: doc.data().item_link,
                    is_active: doc.data().is_active,
                    has_sub_menu: doc.data().has_sub_menu,
                    item_pos: doc.data().item_pos,
                    sub_menu: [],
                    // otherData: doc.data()
                });
            });

            // GETTING SUB MENUES
            firestore.collection('header_menu_categories').orderBy('item_name', 'asc').get().then(querySnapshot => {
                querySnapshot.forEach(doc => {
                    subMenuData.push({
                        item_id: doc.id,
                        parent_id: doc.data().parent_id,
                        item_name: doc.data().item_name,
                        is_active: doc.data().is_active
                    });
                });

                // BUILDING MENU
                mainData.map(item => {
                    if (item.has_sub_menu === true) {
                        return subMenuData.map(sub_item => {
                            if (item.item_id === sub_item.parent_id) {
                                item.sub_menu.push(sub_item);
                            }
                            return item;
                        })
                    }
                });


                dispatch({ type: 'FETCH_MENU_ITEM', data: mainData });
            });
        });
    }
};

使用它打印数据

<ul>
    {
        props.mainMenu && props.mainMenu.map(item => {
            return (
                (item.is_active) &&
                <li key={item.item_id} className={item.has_sub_menu ? 'has-menu-items' : ''}>
                    <a href={item.item_link}>{item.item_name}</a>
                    {
                        (item.has_sub_menu) &&
                        <ul className="sub-menu">
                            {
                                item.sub_menu.map(sub_item => {
                                    return (
                                        <li key={sub_item.item_id}>
                                            <a href={sub_item.item_link}>{sub_item.item_name}</a>
                                        </li>
                                    )
                                })
                            }
                        </ul>
                    }
                </li>
            )
        })
    }
</ul>

【问题讨论】:

  • 第 35 行有什么?
  • var mainData 是从 Firestore 获取的 mainMenu 数据,subMenuData 是 sub_menu 表的数据。
  • 我在 mainData 上使用了地图,并在我将其 id 与 subMenu 的父 id 进行比较之后,检查其是否有具有 has_sub_menu == true 的项目

标签: javascript reactjs firebase google-cloud-firestore


【解决方案1】:

这是一个 eslint 规则:https://eslint.org/docs/rules/array-callback-return

它强制你从任何数组过滤、映射和折叠回调函数中返回一些东西

mainData.map(item => {
  if (item.has_sub_menu === true) {
    return subMenuData.map(sub_item => {
      if (item.item_id === sub_item.parent_id) {
        item.sub_menu.push(sub_item);
      }
      return item;
    })
  }
  // nothing returned here
});

题外话:你确定这个功能真的有用吗?

我怀疑你想这样做:

mainData.forEach(item => {
  if (item.has_sub_menu === true) {
    item.sub_menu = subMenuData.reduce((acc, sub_item) => {
      if (sub_item.parent_id === item.item_id) {
        acc.push(sub_item);
      }
      return acc;
    }, []);
  }
});

【讨论】:

  • 谢谢,我使用了你的功能,它工作得很好。我打算使用 for 循环。但是我怎么能忘记reduce功能。谢谢
  • 我编辑了答案。在这种情况下,您不必使用 Array.map() 创建一个实际上没有在任何地方使用的新数组。在这种情况下使用 Array.forEach() 效率会更好。
  • 非常感谢您的帮助。
【解决方案2】:

这是浏览器控制台还是您的系统终端?看起来更像系统终端,消息说明了一切:"Line 35: Expected to return a value at the end of arrow function array-callback-return" 您很可能没有返回值。如果你映射数组并在回调中你有一个 if -> 如果不满足 if 的条件会发生什么?你不会输入它 - 所以当你不进入 if 语句时你会返回什么 - 你猜对了 - 什么都没有。根据您的操作,您可以返回 false。然后过滤所有元素,只返回具有正值的元素。

【讨论】:

  • 谢谢,最后我发现我没有返回值。我做到了,我的代码有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-01
  • 2021-02-24
相关资源
最近更新 更多