数组的 setState 反应挂钩不保存先前的数组元素

setState react hook for array is not saving prior array elements

我有一个使用 aysnc 和 await 的 API 请求,抓取数据,然后使用 Promise.all 发出第二个请求,这会发出多个 API 带有 id 的请求。那部分效果很好。

但是,当我将数据保存在一个名为“setItem”的 React 钩子中时,它只保存了一个并覆盖了其他的。我在 setItem()

中有一个传播运算符

setItems(...项目, 数据)

数据是来自 API 请求的响应。

我的 API 请求在我的 React 应用程序的顶层,所以我将它拉到它自己的小帮助文件中,这就是为什么“items”和“setItems”是传递的参数。

    import axios from 'axios';
    import BottleNeck from 'bottleneck'

    const limiter = new BottleNeck({
      maxConcurrent: 1, 
      minTime: 333
    })

    export const Request = (items, setItems) => {

      const getData = () => {
        const options = 'newstories' 
        const API_URL = `https://hacker-news.firebaseio.com/v0/${options}.json?print=pretty`;

        return new Promise((resolve, reject) => {
          return resolve(axios.get(API_URL))
        })
      }

      const getIdFromData = (dataId) => {
        const API_URL = `https://hacker-news.firebaseio.com/v0/item/${dataId}.json?print=pretty`;
        return new Promise((resolve, reject) => {
          return resolve(axios.get(API_URL))
        })
      }

      const runAsyncFunctions = async () => {
        const {data} = await getData()

        Promise.all(
          data.map(async (d) => {
            const {data} = await limiter.schedule(() => getIdFromData(d))
           //****************** issue here ************************//
            setItems([...items, data]);
          })
        )
      }
      runAsyncFunctions()

    }

以防万一您想查看 app.js 文件以供参考

    import React, { useState, useEffect } from 'react';
    import './App.css';
    import { SearchBar } from './search-bar';
    import { Results } from './results';
    import { Request } from './helper/request'

    function App() {
      const [input, setInput] = useState('');
      const [items, setItems] = useState([]);

      const handleChange = val => {
        setInput(val)
      }
      // console.log(input)
      // console.log(results)

      // API calls
      // call useEffect here, calls Request(), put results in useEffect

      useEffect(() => {
        Request(items, setItems)
      }, [])

      return (
        <div className="App">
          <SearchBar handleChange={handleChange}/>
          <Results items={items} />
        </div>
      );
    }

    export default App;

在您的 Promise.all return 每个数据处,在您可以与 then 链接之后传递一个包含所有已解析数据的数组。这样你只需要调用一次setItems:

Promise.all(
  data.map(async (d) => {
    const { data } = await limiter.schedule(() => getIdFromData(d));
    return data;
  })
).then((dataResults) => setItems((results) => [...results, ...dataResults]));