我对诺言和使用状态很陌生,但是我已经看了好几个小时了,我无法理解这里的问题,但这可能是我对诺言的理解。任何帮助将不胜感激。
我有一个与响应API的道具水合的成分:
const [trafficData, setTrafficData] = useState();
getTrafficDetails().then(r => {
setTrafficData(r);
})
<TrafficWidget incomingData={trafficData} />
交通小部件组件
const TrafficWidgetComponent = (data) => {
let [trafficDetails, setTrafficDetails] = useState(null);
if(data){
const toShow = data.map((item) => {
//return some jsx
return(<div>{item.roadName}: {item.trafficCondition}</div>)
})
setTrafficDetails(toShow);
}
return(<>{toShow}</>)
}
我的应用程序消耗的promise中返回的api的方法在这里:
const getTrafficDetails = (linkOne, linkTwo) => {
const a = fetch(linkOne)
.then((data) => data.json())
.then((data) => data.TRAFFIC_INFO);
const b = fetch(linkTwo)
.then((data) => data.json())
.then((data) => data.TRAFFIC_INFO);
return Promise.all([a, b]).then((td) => {
const copiedData = [...td]
//do something with copiedData to combine all objects into array of objects and add new properties
return combineAndAddMetadata(copiedData)
});
};
combineAndAddMetadata
const combineAndAddMetadata = (trafficData) => {
const combinedTrafficObject = [].concat(...trafficData);
const toReturn = [];
combinedTrafficObject.map((trafficDataItem) => {
const { id, cotwoEmissions, utl } = trafficDataItem;
const filteredObject = toReturn.find((item) => item.id === id);
if (!filteredObject) {
trafficDataItem.totalEmission = currencyFormatter(cotwoEmissions * utl);
toReturn.push(trafficDataItem);
} else {
const totalCSL = cotwoEmissions * filteredObject.utl;
filteredObject.utl += utl;
filteredObject.totalEmission = totalCSL;
filteredObject.totalEmissionFormatted = currencyFormatter(totalCSL);
}
});
此方法返回的数据是对象数组:[{...}, {...}, etc]
,我可以在控制台中看到它。
我无法理解的是,为什么即使我复制了回调,来自td
中.then上的getTrafficDetails
上的变量现在仍使用新的元数据进行了更新。
即使很奇怪,当我检查通过此方法进入TrafficWidget
组件中的数据时,它也会转换为一个对象,其中包含所请求的数据,其长度为0,形式为{{1} },如果我随后通过{data: [{},{}]}
在TrafficWidget组件中访问,则会导致无限循环,从而导致崩溃。 (尽管在设置data.data
之前登录r
会以正确的格式显示正确的数据)
有人能对此有所启发吗?
编辑:添加了我从抓取中获得的回复以及我最终想要得到的回复
例如,数据来自提取网址1:
trafficData
例如数据来自提取网址2:
[{id: '000', cotwoEmissions: 345, utl: 45},{id: '001', cotwoEmissions: 345, utl: 34}]
我在合并中尝试做的事情是有一个对象数组,将这些对象组合在一起,其中id相同且位置相同,utl值被组合并乘以cotwoEmissions值(对于给定的ID)。然后,我基于此向每个对象添加一些额外的属性,并返回一个包含所有对象的新数组。
因此上述内容作为输出将变为:
[{id: '000', cotwoEmissions: 345, utl: 32},{id: '003', cotwoEmissions: 345, utl: 45} ]
答案 0 :(得分:0)
无法解决所有奇怪的问题,但是在转换函数内部,您首先销毁trafficData项,然后再对其进行修改。这也会修改td变量,因为它保留了对相同项目的引用。
您可能想要的是创建一个具有修改后的值和旧值(已解构)的新对象,并将该新创建的项添加到toReturn中。
一般来说,这是一个好习惯,可以避免这样的混乱,不要修改输入参数,而是在某些级别上进行了更改(如果实际上已更改),则复制并返回一个新对象。 这主要用于以下情况:找不到过滤对象(第一次修改项目),找到对象时,您知道所找到的对象是您在此函数内创建的对象(假设您修改您的代码以创建一个新对象以推送到toReturn),因此再次进行修改应该是安全的。