在 useEffect() 中未调用函数

Posted

技术标签:

【中文标题】在 useEffect() 中未调用函数【英文标题】:Function not getting called in useEffect() 【发布时间】:2022-01-09 09:40:40 【问题描述】:

我希望每次渲染组件时都调用这两个函数,但它们没有被执行。当我将函数放在依赖数组中时,它会导致无限循环。知道为什么他们没有被调用吗?

  function PortfolioComponent() 
  const [requestedAssets, setRequestedAssets] = useState([]);
  const [assets, setAssets] = useState([]);

  useEffect(() => 
    async function calcValue() 
      Promise.all(
        requestedAssets.map(async function (asset) 
          try 
            const response = await axios.get(assetData(asset.AssetId));
            let cp = response.data.market_data.current_price.eur;
            let value = Number(cp) * Number(asset.Amount);
            return  ...asset, value: value, price: cp ;
           catch (error) 
            console.log(error.response.data.error);
            throw error;
          
        )
      )
        .then((newAssetArray) => 
          setAssets(newAssetArray);
          console.log(newAssetArray);
          console.log(assets);
        )
        .catch((error) => 
          console.log(error);
        );
    

    async function getAssets() 
      try 
        const response = await axios.get("http://localhost:4200/assets");
        // Do as you wish with response here
        const assetResponse = response.data.rows;
        setRequestedAssets(assetResponse);
        console.log(requestedAssets);
       catch (error) 
        console.log(error.response.data.error);
      
    

    getAssets();
    calcValue();
  , []);

还有一些我刚刚发现的奇怪行为......

比如这行代码:

        let cp = await response.data.market_data.current_price.eur;

当我删除 await 关键字并将其保存在 VS 代码中时,数据按预期检索。但是,当我刷新浏览器时,数组再次为空。当我再次添加 await 关键字并保存时也是如此。同样的事情也会发生。

【问题讨论】:

在我看来,您根本不需要 useEffect 挂钩。直接调用函数即可。 useEffect 对我来说似乎找到了。问题似乎与被调用的两个函数有关。尝试删除函数的内容,然后在其中放置一个控制台,看看它是否工作 @FloRagossnig 你不想在反应组件中直接调用它们,因为这会导致重新渲染问题 【参考方案1】:

这对我有用。因此,我没有为 requestedAssets 使用 useState 变量,而是在 getAssets 方法中创建了一个变量。我不完全确定为什么这会起作用,而不是相反。但是,如果有人能解释一下,那就太好了。

 function PortfolioComponent() 
      //const [requestedAssets, setRequestedAssets] = useState([]);
      const [assets, setAssets] = useState([]);
    
      useEffect(() => 
        async function getAssets() 
          const response = await axios.get("http://localhost:4200/assets");
          const requestedAssets = response.data.rows;
          console.log(requestedAssets);
    
          Promise.all(
            requestedAssets.map(async function (asset) 
              try 
                const response = await axios.get(assetData(asset.AssetId));
                let cp = response.data.market_data.current_price.eur;
                let value = Number(cp) * Number(asset.Amount);
                return  ...asset, value: value, price: cp ;
               catch (error) 
                console.log(error.response.data.error);
                throw error;
              
            )
          )
            .then((newAssetArray) => 
              setAssets(newAssetArray);
              console.log(newAssetArray);
              console.log(assets);
            )
            .catch((error) => 
              console.log(error);
            );
        
    
        getAssets();
      , []);

【讨论】:

【参考方案2】:

建议在useEffect 中声明您的函数,请参阅official documentation。如果您继续在文档中滚动,他们甚至有一个与您类似的示例,带有 async 函数。

如果出于某种原因,您确实需要在useEffect 之外声明您的函数,您可以使用useCallback,它允许您在依赖数组中声明它们。像这样的:

const getAssets = useCallback(async() => 
  try 
    const response = await axios.get("http://localhost:4200/assets");
    // Do as you wish with response here
    const assetResponse = response.data.rows;
    setRequestedAssets(assetResponse);
    console.log(requestedAssets);
   catch (error) 
    console.log(error.response.data.error);
  
, [requestedAssets])

useEffect(() => 
  getAssets()
, [getAssets])

您还可以在blog here 中查看我是否需要将函数指定为效果依赖项?部分了解更多信息。

PS:这篇博客来自丹·阿布拉莫夫,他是 React 的创建者之一,来源非常可靠;)

【讨论】:

这会导致无限循环 您是否首先尝试在 useEffect 中声明您的函数?这不应该导致无限循环。还是你用的是回调方式? 如果你使用回调,你需要检查你的依赖。例如,getAsset 函数正在改变requestedAssets 的状态,因此它需要是一个依赖项。另一种选择是在尝试运行之前检查requestedAssets 是否为空数组(在useEffect 中)。也许你可以提供更多细节?我还更新了答案以包含依赖项(错过了) 我更新了问题。我在 useEffect 中声明了该函数,但仍然无法正常工作。这些函数似乎被调用,因为 console.logs 被记录到控制台但数组是空的?我将提供屏幕截图 我也尝试了回调方法并将请求的资产添加为依赖项,但这也是一个无限循环。

以上是关于在 useEffect() 中未调用函数的主要内容,如果未能解决你的问题,请参考以下文章

为啥 useEffect 钩子在第一次渲染时不调用函数?

为啥 useEffect 之外的函数被调用,而没有依赖数组的 useEffect 内部的函数却没有?

我应该在哪里声明在 useEffect() 钩子中调用的函数?

无效的挂钩调用。钩子只能在反应函数组件内部使用...... useEffect,redux

在 useEffect() 钩子中从父级传递的子级调用函数,React

React Hooks-调用依赖于“一次” useEffect的状态的函数的最佳位置?