javascript - 如何从自定义 react 钩子(Hook)丰富数据

标签 javascript reactjs react-hooks

在我的 React 应用程序中,我创建了一个自定义 Hook ,它会在使用时返回一组数据。

它的使用方式类似于constprojects = useProjects();

它是一个对象数组,我们可以假设它看起来像这样:

 [{project_id : 123 , name : 'p1'} , {project_id : 1234 , name : 'p2'} ]

现在我需要使用 API 中的数据来丰富这些数据。所以我必须遍历项目并基本上向每个对象添加一个新字段,因此新的对象数组将如下所示:

[{project_id : 123 , name : 'p1' field3: 'api data'} , {project_id : 1234 , name : 'p2' , field3: 'api data1' } ]

我怎样才能实现这个目标?

我所做的是循环访问项目数据并直接在循环内添加字段。但我不知道我是否应该像这样改变这些数据?我希望看看这是否是好的做法。

最佳答案

有几种方法可以解决这个问题 - 这完全取决于您如何从 API 获取数据。如果你想将其注入(inject)到钩子(Hook)中,你可以这样做 -

const DEFAULT_PROJECTS = [
    { project_id : 123, name: 'p1' }, 
    { project_id : 1234, name: 'p2' },
];

const useProjects = (dataFromApi) => {
    // Assuming that dataFromApi is what you got back from your API call, 
    // and it's a dictionary keyed on the project_id.
    return useMemo(() => {
        return DEFAULT_PROJECTS.map(proj => {
            const extraData = dataFromApi.get(proj.project_id) || {};
            
            return {
                ...proj,
                ...extraData,
            };
        });
    }, [dataFromApi]);
};

如果 dataFromApi 总是在变化,那么这里的 useMemo 并不是很有帮助 - 它每次都会重建返回的对象。

如果你想获取数据作为你的钩子(Hook)的一部分,你可以这样做 -

import { useEffect, useMemo, useState } from 'react';

const DEFAULT_PROJECTS = [
  { project_id : 123, name: 'p1' },
  { project_id : 1234, name: 'p2' },
];

const useProjects = () => {
  const [dataFromApi, setDataFromApi] = useState(null);

  useEffect(() => {
    if (!!dataFromApi) return;

    // Simulate the data fetch
    const fetchData = async () => {
      return new Promise(resolve => {
        setTimeout(() => {
          const map = new Map();
          map.set(123, { 
            field3: 'api data',
            field4: 'other data',
          });

          setDataFromApi(map);
        }, 2000);
      });
    };

    fetchData();
  }, [dataFromApi]);

  return useMemo(() => {
    let extraData = dataFromApi || new Map();

    return DEFAULT_PROJECTS.map(proj => {
      const extraFields = extraData.get(proj.project_id) || {};

      return {
          ...proj,
          ...extraFields,
      };
    });
  }, [dataFromApi]);
}

export default useProjects;

Here's a code sandbox that shows it in action.

关于javascript - 如何从自定义 react 钩子(Hook)丰富数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64653560/

相关文章:

Javascript DatePicker 格式年份为 2 位数字

reactjs - 避免在上下文更新时运行效果 Hook

javascript - useSelector 或 useContext

reactjs - 在我的案例中执行 React Router 历史推送时如何滚动到页面

reactjs - React-native-navigation 导航时更改屏幕方向

javascript - 为什么我无法清除 setInterval?

Javascript - 迭代中未定义的数组

javascript - 谁能帮助我如何在 Meteor React 应用程序中使用 jQuery-formBuilder 插件

javascript - Ext Js Grid,如何获取特定列所有行值和总和?

javascript - 使用 ReactJS 从 JSON 获取数据时遇到问题