为了账号安全,请及时绑定邮箱和手机立即绑定

如何从自定义反应钩子丰富数据

如何从自定义反应钩子丰富数据

心有法竹 2023-07-06 14:42:08
在我的 React 应用程序中,我创建了一个自定义钩子,它在使用时返回一组数据。它的用法就像const projects = 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' } ]我怎样才能做到这一点?我所做的是循环访问项目数据并直接在循环内添加字段。但我不知道我是否应该像这样改变这些数据?我希望看看这是否是好的做法。
查看完整描述

1 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

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


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]);

};

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


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


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;

这是一个代码沙箱,显示了它的实际效果。


查看完整回答
反对 回复 2023-07-06
  • 1 回答
  • 0 关注
  • 132 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信