在react base chrome扩展中使用长时间连接时无法获取状态值



我有一个Popup.jsx和一个Background.js。这个弹出窗口创建了一个与后台service worker的长期连接。

我在我的Popup.jsx中保持一个状态,它看起来像这样

const [projectDetail, setProjectDetail] = useState({ projectCode: null })

我的Popup.jsxuseEffect是这样的,

useEffect(() => {
port = chrome.runtime.connect({ name: 'Background Connection' })
port.onMessage.addListener(({ action, payload }) => {
switch (action) {
case ACTION.SET_PROJECT_DETAIL:
setProjectDetail(payload);
break;

case ACTION.CHECK_STATE:
console.log(projectDetail)
break;


default:
break;
}

})
port.postMessage({ action: ACTION.GET_PROJECT_DETAIL })
return () => {
port.disconnect()
}
}, [])

正如您所看到的,在port变量(在组件作用域之外定义)上附加onMessage的侦听器后,我正在向Background.js发送消息以获取项目详细信息。Background.js按照以下代码响应:

chrome.runtime.onConnect.addListener(function (port) {
// console.log("🚀 ~ file: index.js ~ line 182 ~ chrome.runtime.onConnect.addListener ~ port", port)
port.onMessage.addListener(function ({ action, payload }) {
if (action === ACTION.GET_PROJECT_DETAIL) {
port.postMessage({ action: ACTION.SET_PROJECT_DETAIL, payload: { projectCode: "Some value"} })
}
// ...Removed more code for brevity
});
});

假设我有一个用户交互按钮,它告诉Background.jsPopup.jsx发送一条与case ACTION.CHECK_STATE:匹配的消息,所以很明显,我希望Popup.jsx能够控制台记录{projectCode: "Some value"}的值,因为组件中的状态已经更新(我已经通过使用ReactDevTools验证了它)。

但是,它打印的{ projectCode: null }是初始状态值。

注意:用户交互不会在组件挂载后立即发生,所以我不是想在设置后立即获得状态值。

我无法在addListener的回调函数中获得更新的状态值。我不知道我哪里做错了。

不能工作的原因是port变量是在功能组件本身之外声明的。

最初,Popup.jsx是这样定义的,

//...import statements
let port = null;
const Popup = () => {
port = chrome.runtime.connect({ name: 'Background Connection' });

//...more code
}

之后,我把它改成,

//...import statements
const Popup = () => {
let port = chrome.runtime.connect({ name: 'Background Connection' });

//...more code
}

我不能确切地说到底是什么原因。然而,在我看来,这似乎是范围问题。

最新更新