我在写一个 chrome 插件
content script 会给页面增加一个按钮,点击这个按钮后
content script
会发消息,service worker
和sidePanel
都会监听这个消息service worker
收到消息后,会打开侧边栏sidePanel
监听消息,然后会把页面信息渲染出来service worker
的代码
chrome.runtime.onMessage.addListener((req, sender) => {
if (req.type === 'openSidePanel') {
chrome.sidePanel.open({ tabId: sender.tab.id });
}
});
侧边栏的伪代码:
const SidePanel = () =>{
const [info, setInfo] = useState('');
useEffect(()=>{
chrome.runtime.onMessage.addListener((req)=> setInfo(req.info))
})
return ({info===''?'loading...':info})
}
但是有个非常奇怪的现象,就是我第一次点击,侧边栏能正常打开,但是会显示 loading
只有第二次点击之后,才会把 info 信息渲染出来
我的猜测是,第一次点击的时候,组件刚渲染出来,useEffect 里面监听消息没有生效,第二次点击后,组件已经渲染完毕了,useEffect 里面可以监听到消息了,如果是这样的话,应该怎么解决?
不是很熟悉前端,请教一下大家怎么解决
1
wdking 176 天前 1
使用 uselayouteffect
|
2
realJamespond 176 天前 1
useEffect(()=>{
chrome.runtime.onMessage.addListener((req)=> setInfo(req.info)) },[]) 要加 deps 啊,不然每次 render 都执行 |
3
zkkz 176 天前 1
在 service worker 暂存信息,等 SidePanel 渲染完成后,再与 service worker 通信获取信息。
|
4
Albertcord 176 天前 1
怀疑是没有同步更新导致的,可以尝试在侧边栏实现里这么写:
```JavaScript import {flushSync} from 'react-dom'; // ... useEffect(()=>{ chrome.runtime.onMessage.addListener((req)=> { flushSync(() => { setInfo(req.info); }); }) return () => { // unsubscribe addListener } }, []) ``` |