在我的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' } ]
我该如何实现?
我所做的是遍历项目数据,并将字段直接添加到循环中。但是我不知道我是否应该像这样突变这些数据?我希望看看这是否是个好习惯。
答案 0 :(得分:1)
有几种方法可以解决此问题-这完全取决于您如何从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;