通过数组和 API 调用进行异步映射时如何在 React 中设置状态
How to setState in React when async mapping through array and API call
我正在尝试在 React 中通过我的收藏夹中的 map() 来从状态中的每个条目中获取数据。数据应该存储在另一个状态stocks中,并以table.
显示
Map() 通过状态和获取数据有效,我可以在控制台日志中看到日期。但不会存入state。
如何将数据添加到状态?
代码如下:
// Calling the function on component mount
useEffect(() => {
tableFetch();
}, []);
const [favorites, setFavorites] = useState(["aapl", "arlv"]);
const [stocks, setStocks] = useState([]);
// fetch symbol data and stores it in stocks
const tableFetch = () => {
favorites.map( async (favorites) => {
const data = await fetch(
`https://cloud.iexapis.com/stable/stock/${favorites}/quote?token=${token}`
);
const stocksData = await data.json();
console.log(stocksData)
setStocks(stocksData);
});
}
这里有一些问题。
- 当您在获得响应后进行 API 调用时,状态将被新数据覆盖或可能会发布范围可用性
建议:
2. 为什么不进行多次 API 调用,当它们结算时,收集所有信息然后设置状态。
useEffect(() => {
tableFetch();
}, []);
const tableFetch = async () => {
// Note: the below code will create urls & make parallel calls
let axiosFetch = favorites.reduce((axiosCalls, url) => {
axiosCalls.push(axios.get(`https://reqres.in/api/users?page=${url}`));
return axiosCalls;
}, []);
// Here promises will settle and will collect all the data.
await axios
.all(axiosFetch)
.then((data) => {
let dataCollected = data.reduce((dataCollected, response) => {
dataCollected = dataCollected.concat(response.data.data);
return dataCollected;
}, []);
// After collecting all the data we can set data into state at once.
setStocks(dataCollected);
})
.catch((error) => {
console.log("collect errors", error);
});
};
Sample Code Example, you can play around
Note: I was using Axios library, the same thing can be done using fetch too.
我已经使用 fetch 完成了这些更改,希望对您有所帮助。
const tableFetch = async () => {
// Note: the below code will create urls & make parallel calls
let urls = favorites.reduce((axiosCalls, url) => {
axiosCalls.push(`https://reqres.in/api/users?page=${url}`);
return axiosCalls;
}, []);
const texts = await Promise.all(
urls.map(async (url) => {
const resp = await fetch(url);
return resp.json();
})
);
let dataCollected = texts.reduce((dataCollected, response) => {
dataCollected = dataCollected.concat(response.data);
return dataCollected;
}, []);
// After collecting all the data we can set data into state at once.
setStocks(dataCollected);
};
我正在尝试在 React 中通过我的收藏夹中的 map() 来从状态中的每个条目中获取数据。数据应该存储在另一个状态stocks中,并以table.
显示Map() 通过状态和获取数据有效,我可以在控制台日志中看到日期。但不会存入state。
如何将数据添加到状态?
代码如下:
// Calling the function on component mount
useEffect(() => {
tableFetch();
}, []);
const [favorites, setFavorites] = useState(["aapl", "arlv"]);
const [stocks, setStocks] = useState([]);
// fetch symbol data and stores it in stocks
const tableFetch = () => {
favorites.map( async (favorites) => {
const data = await fetch(
`https://cloud.iexapis.com/stable/stock/${favorites}/quote?token=${token}`
);
const stocksData = await data.json();
console.log(stocksData)
setStocks(stocksData);
});
}
这里有一些问题。
- 当您在获得响应后进行 API 调用时,状态将被新数据覆盖或可能会发布范围可用性
建议: 2. 为什么不进行多次 API 调用,当它们结算时,收集所有信息然后设置状态。
useEffect(() => {
tableFetch();
}, []);
const tableFetch = async () => {
// Note: the below code will create urls & make parallel calls
let axiosFetch = favorites.reduce((axiosCalls, url) => {
axiosCalls.push(axios.get(`https://reqres.in/api/users?page=${url}`));
return axiosCalls;
}, []);
// Here promises will settle and will collect all the data.
await axios
.all(axiosFetch)
.then((data) => {
let dataCollected = data.reduce((dataCollected, response) => {
dataCollected = dataCollected.concat(response.data.data);
return dataCollected;
}, []);
// After collecting all the data we can set data into state at once.
setStocks(dataCollected);
})
.catch((error) => {
console.log("collect errors", error);
});
};
Sample Code Example, you can play around
Note: I was using Axios library, the same thing can be done using fetch too.
我已经使用 fetch 完成了这些更改,希望对您有所帮助。
const tableFetch = async () => {
// Note: the below code will create urls & make parallel calls
let urls = favorites.reduce((axiosCalls, url) => {
axiosCalls.push(`https://reqres.in/api/users?page=${url}`);
return axiosCalls;
}, []);
const texts = await Promise.all(
urls.map(async (url) => {
const resp = await fetch(url);
return resp.json();
})
);
let dataCollected = texts.reduce((dataCollected, response) => {
dataCollected = dataCollected.concat(response.data);
return dataCollected;
}, []);
// After collecting all the data we can set data into state at once.
setStocks(dataCollected);
};