React 组件渲染问题

izzy27 · 2024-5-11 16:05:03 · 119 次点击
我在写一个 chrome 插件

content script 会给页面增加一个按钮,点击这个按钮后
1. `content script`会发消息,`service worker`和`sidePanel`都会监听这个消息
2. `service worker`收到消息后,会打开侧边栏
3. `sidePanel`监听消息,然后会把页面信息渲染出来

`service worker`的代码
```js
chrome.runtime.onMessage.addListener((req, sender) => {
  if (req.type === 'openSidePanel') {
    chrome.sidePanel.open({ tabId: sender.tab.id });
  }
});
```

侧边栏的伪代码:
```js
const SidePanel = () =>{
        const [info, setInfo] = useState('');
   
    useEffect(()=>{
            chrome.runtime.onMessage.addListener((req)=> setInfo(req.info))
    })

        return ({info===''?'loading...':info})
}
```
但是有个非常奇怪的现象,就是我第一次点击,侧边栏能正常打开,但是会显示 loading

只有第二次点击之后,才会把 info 信息渲染出来

我的猜测是,第一次点击的时候,组件刚渲染出来,useEffect 里面监听消息没有生效,第二次点击后,组件已经渲染完毕了,useEffect 里面可以监听到消息了,如果是这样的话,应该怎么解决?

不是很熟悉前端,请教一下大家怎么解决
举报· 119 次点击
登录 注册 站外分享
4 条回复  
wdking 小成 2024-5-11 16:13:00
使用 uselayouteffect
realJamespond 小成 2024-5-11 16:27:36
useEffect(()=>{
            chrome.runtime.onMessage.addListener((req)=> setInfo(req.info))
    },[])
要加 deps 啊,不然每次 render 都执行
zkkz 小成 2024-5-11 16:31:04
在 service worker 暂存信息,等 SidePanel 渲染完成后,再与 service worker 通信获取信息。
Albertcord 初学 2024-5-11 16:35:18
怀疑是没有同步更新导致的,可以尝试在侧边栏实现里这么写:  
```JavaScript
   import {flushSync} from 'react-dom';
   // ...
    useEffect(()=>{
            chrome.runtime.onMessage.addListener((req)=> {
            flushSync(() => {
                setInfo(req.info);
            });
        })
        return () => {
             // unsubscribe addListener
        }
    }, [])
```
返回顶部