【问题标题】:Function not getting called in useEffect()在 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 你不想在反应组件中直接调用它们,因为这会导致重新渲染问题

标签: javascript reactjs axios state use-effect


【解决方案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 被记录到控制台但数组是空的?我将提供屏幕截图
    • 我也尝试了回调方法并将请求的资产添加为依赖项,但这也是一个无限循环。
    猜你喜欢
    • 2021-02-11
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 2020-08-17
    • 1970-01-01
    • 2021-02-26
    • 2019-11-12
    相关资源
    最近更新 更多