【问题标题】:How to fix multiple call fetch data in forEach() using React Hooks如何使用 React Hooks 在 forEach() 中修复多个调用获取数据
【发布时间】:2020-10-07 15:16:09
【问题描述】:

在 react Hooks 中,我试图从 API 数组中获取数据,但在 Foreach 函数中,API 调用会导致无穷大。 如何解决这个问题?

const [symbols, setSymbols] = useState([]);

getPortfolioSymbolList(portfolio_name).then(data => data.json()).then(res => {

   res.forEach((symbol_data)=>{
      fetchPrice(symbol_data.symbol).then(price => {
         setSymbols(price);

      });
          
   })
}

function fetchPrice(symbol){
    const price = fetch(`api_url`)
    .then(chart => chart.json())
    return price;
}

这里,调用 fetchPrice() 导致无限。

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    设置状态总是会导致重新渲染

    在您的代码中发生的情况是发出请求,然后设置数据导致重新呈现。然后由于重新渲染,再次发出请求并再次设置状态并再次导致重新渲染。

    如果您有数据请求,您可能希望输入React.useEffect,这样它只会请求一次。

    React.useEffect(() => {
      /* your data request and data set */
    }, []); // the [] will only fire on mount.
    

    【讨论】:

      【解决方案2】:

      是因为您在 forEach 中调用 setSymbols 会使组件重新渲染(重新加载) - 这意味着您的所有主要组件函数都被一次又一次地调用...... getPortfolioSymbolList 也是。您必须使用useEffect 挂钩来解决此问题。您的 getPortfolioSymbolList() API 调用应该在 useEffect 中。

      https://reactjs.org/docs/hooks-effect.html

      【讨论】:

        【解决方案3】:

        问题

        您的第一个符号在您的 API 调用中更新,这会触发调用 API 调用的组件的重新渲染以进入无限循环。

        解决方案

        1. 将您的API 包裹在您的useEffect 中。 useEffect 中的函数只会被调用一次。 See useEffect docs here
        2. 需要使用for await of进行异步循环。 forEach 不能异步循环。 See for await of docs here
        3. 收集完所有数据后更新您的符号。
        function Symbols() {
          const [symbols, setSymbols] = useState([]);
        
          React.useEffect(() => {
            async function fetchSymbols() {
              const portfolio = await getPortfolioSymbolList(portfolio_name);
              const jsonPortfolios = await data.json();
        
              const symbols = [];
              for await (let jsonPortfolio of jsonPortfolios) {
                const price = await fetchPrice(jsonPortfolio.symbol);
                symbols.push(price);
              }
        
              setSymbols(symbols);
            }
        
            fetchSymbols();
          }, []);
        
          return /** JSX **/
        }
        

        【讨论】:

          猜你喜欢
          • 2019-08-26
          • 2020-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-20
          • 2020-07-05
          • 1970-01-01
          • 2021-05-10
          • 1970-01-01
          相关资源
          最近更新 更多