我试图在调用
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
}, [])
您传入了一个空的依赖项数组。这意味着效果会在第一次渲染时设置,并且不会再设置。由于它是在第一次渲染时设置的,因此
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