读取回调函数内部时,React 状态未定义

问题描述 投票:0回答:1

我试图在调用

chrome.tabs.onUpdated.addListener
的回调时读取反应状态,但状态值似乎未定义,即使它之前已设置。

这是我制作的钩子。

export const useCurrentTab = () => {
    const [currentTab, setCurrentTab] = useState<chrome.tabs.Tab | undefined>(undefined)
    const [activeTabId, setActiveTabId] = useState<number | undefined>(undefined)

    const getActiveTab = async () => {
        const [tab] = await chrome.tabs.query({ active: true, currentWindow: true })
        console.log(`Setting current tab id to ${tab?.id}`)
        setActiveTabId((prevActiveTabId) => tab?.id || prevActiveTabId)
        return tab
    }

    const updateCurrentTab = (
        tabId: number,
        changeInfo: chrome.tabs.TabChangeInfo,
        tab: chrome.tabs.Tab
    ) => {
        console.log("updateCurrentTab", activeTabId, currentTab, tabId);
        if (changeInfo.status === 'complete' && tabId === activeTabId) {
            console.log(`Tab ${tabId} status changed to ${changeInfo.status}`)
            setCurrentTab(tab)
        }
    }

    useEffect(() => {
        getActiveTab().then((tab) => {
            if (tab && tab.status === 'complete') {
                setCurrentTab(tab)
            }
        })

        chrome.tabs.onUpdated.addListener(updateCurrentTab)

        return () => {
            chrome.tabs.onUpdated.removeListener(updateCurrentTab)
        }
    }, [])

    return currentTab
}

问题是

currentTab
在页面加载后没有更新,我已经通过添加控制台日志进行了调试并指出了问题。

console.log("updateCurrentTab", activeTabId, currentTab, tabId);

记录时,显示

activeTabId
未定义,因此此处对
tabId === activeTabId
的检查失败。

这是按顺序排列的控制台日志。

current-tab.tsx:15 Setting current tab id to 1494595641
current-tab.tsx:25 updateCurrentTab undefined undefined 1494595641
reactjs google-chrome-extension plasmo
1个回答
0
投票
 }, [])

您传入了一个空的依赖项数组。这意味着效果会在第一次渲染时设置,并且不会再设置。由于它是在第一次渲染时设置的,因此

updateCurrentTab
会覆盖第一次渲染期间存在的状态值,即
undefined

要解决此问题,您需要让效果随着状态变化而更新。我假设

getActiveTab
仍然只应该被调用一次,所以你需要将代码分成两个效果,这样它们就可以有不同的依赖数组。另外,我建议您将函数移至效果内部,除非组件的其他部分需要它们

useEffect(() => {
  const getActiveTab = async () => {
    const [tab] = await chrome.tabs.query({
      active: true,
      currentWindow: true,
    });
    console.log(`Setting current tab id to ${tab?.id}`);
    setActiveTabId((prevActiveTabId) => tab?.id || prevActiveTabId);
    return tab;
  };

  getActiveTab().then((tab) => {
    if (tab && tab.status === "complete") {
      setCurrentTab(tab);
    }
  });
}, []);

useEffect(() => {
  const updateCurrentTab = (
    tabId: number,
    changeInfo: chrome.tabs.TabChangeInfo,
    tab: chrome.tabs.Tab,
  ) => {
    console.log("updateCurrentTab", activeTabId, currentTab, tabId);
    if (changeInfo.status === "complete" && tabId === activeTabId) {
      console.log(`Tab ${tabId} status changed to ${changeInfo.status}`);
      setCurrentTab(tab);
    }
  };

  chrome.tabs.onUpdated.addListener(updateCurrentTab);

  return () => {
    chrome.tabs.onUpdated.removeListener(updateCurrentTab);
  };
}, [activeTabId, currentTab]); // <------- new dependency array
© www.soinside.com 2019 - 2024. All rights reserved.