簡體   English   中英

setState 在 useEffect 中使用其回調導致無限循環

[英]setState using its callback inside useEffect causing infinite looping

我知道這是一個關於useEffectuseState無限循環的過度提問。 我已經閱讀了幾乎所有關於它的問題,並在互聯網上進行了搜索,以便在發布之前嘗試修復它。 最近的文章,我讀了這一個

之前,我閱讀文章我useState內部功能useEffect是沒有useState的回調,所以這是我認為這是造成問題的原因。 但是從這里移動它之后:

setNotifications({
  ...notifications,
  [type]: {
    ...notifications[type],
    active: portfolioSettings[type],
    payload: {
      ...notifications[type].payload,
      [pKey]: portfolioSettings[pKey],
    },
  },
});

對此:

setNotifications((currState) => ({
  ...currState,
  [type]: {
    ...currState[type],
    active: portfolioSettings[type],
    payload: {
      ...currState[type].payload,
      [pKey]: portfolioSettings[pKey],
    },
  },
}));

不幸的是,無限循環仍然存在。 這是我在這個組件中使用的所有useEffect函數(最后一個是導致無限循環的函數)。

// Set default selected portfolio to the active portfolio
useEffect(() => {
  let mounted = true;

  const setPortfolioData = () => {
    if (activePortfolio) {
      const portfolioId = activePortfolio.id;
      const portfolioName = activePortfolio.name;
      setSelectedPortfolio({
        portfolioId,
        portfolioName,
      });
    }
  };

  if (mounted) setPortfolioData();

  return () => {
    mounted = false;
  };
}, [activePortfolio]);

// Set all the categories if no category is set
useEffect(() => {
  let mounted = true;

  if (mounted && allCvmCategories) {
    const allCvmCategoriesNames = allCvmCategories.map((c) => c);
    setNotifications((currState) => ({
      ...currState,
      isCvmNotificationEnabled: {
        ...currState.isCvmNotificationEnabled,
        payload: {
          ...currState.isCvmNotificationEnabled.payload,
          cvmCategories: allCvmCategoriesNames,
        },
      },
    }));
    setIsCvmCategoriesReady(true);
  }

  return () => {
    mounted = false;
  };
}, [allCvmCategories]);

// THE ONE WHICH IS CAUSING INFINITE LOOPING
// THE notificationsTypes AND notificationsInitialState
// ARE DECLARED IN THE ROOT OF THE JSX FILE
// OUT OF THE FUNCTIONAL COMPONENT
useEffect(() => {
  let mounted = true;

  if (
    mounted &&
    isCvmCategoriesReady &&
    allPortfolios &&
    selectedPortfolio.portfolioId
  ) {
    const { portfolioId } = selectedPortfolio;
    const portfolioSettings = allPortfolios[portfolioId].settings;

    if (portfolioSettings) {
      notificationsTypes.forEach((type) => {
        if (Object.prototype.hasOwnProperty.call(portfolioSettings, type)) {
          const { payloadKeys } = notificationsInitialState[type];
          if (payloadKeys.length > 0) {
            payloadKeys.forEach((pKey) => {
              if (
                Object.prototype.hasOwnProperty.call(portfolioSettings, pKey)
              ) {
                setNotifications((currState) => ({
                  ...currState,
                  [type]: {
                    ...currState[type],
                    active: portfolioSettings[type],
                    payload: {
                      ...currState[type].payload,
                      [pKey]: portfolioSettings[pKey],
                    },
                  },
                }));
              }
            });
          } else {
            setNotifications((currState) => ({
              ...currState,
              [type]: {
                ...currState[type],
                active: portfolioSettings[type],
              },
            }));
          }
        }
      });
    }
  }

  return () => {
    mounted = false;
  };
}, [allPortfolios, isCvmCategoriesReady, selectedPortfolio]);

感謝您的回復。 我發現了問題,它與我使用(SWR)進行提取的鈎子有關。 使allPortfolios一直在變化。 我已將它固定在一個新的自定義掛鈎中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM