【发布时间】:2021-12-13 15:01:31
【问题描述】:
我正在使用 Electron 和 React 开发桌面应用程序。为了在这两者之间进行通信,我使用了 contextBridge 方法,如下所示:
contextBridge.exposeInMainWorld(
'api', {
send: (channel, data) => {
let validChannels = [
'getProjectId',
'getTaskDetails',
and so on...
]
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, data)
}
},
receive: (channel, func) => {
let validChannels = [
'taskDetails',
'projectId',
and so on...
]
if (validChannels.includes(channel)) {
const subscription = (event, ...args) => func(...args)
ipcRenderer.on(channel, subscription)
return () => {
console.log('Removing listener: ', channel)
ipcRenderer.removeListener(channel, subscription)
}
}
}
}
)
现在,在 React 中,我在 useEffect 钩子中调用这个 receive 调用,并带有一个空的依赖数组。如下:
useEffect(() => {
const projectIdEvent = window.api.receive('projectId', (id) => {
setProjectId(id)
})
console.log('projectIdEvent', projectIdEvent)
const taskDetailEvent = window.api.receive('taskDetails', (data) => {
setTaskDetail(data)
setLoading(false)
})
console.log('taskDetailEvent', taskDetailEvent)
return () => {
console.log('Cleanup function...')
projectIdEvent()
taskDetailEvent()
}
}, [])
当这个组件第一次挂载时,一切正常,上面的日志如下:
projectIdEvent ƒ () { [native code] }
taskDetailEvent ƒ () { [native code] }
如果在任何情况下都卸载了此组件,则会触发清理代码,这也是预期的:
Cleanup function...
Removing listener: projectId
Removing listener: taskDetails
但是,当这个组件再次挂载时,这些 receive 函数不会被添加和触发。同样在添加的日志中,我越来越不确定:
projectIdEvent undefined
taskDetailEvent undefined
我不清楚为什么没有添加这些,我确认当这个组件安装在第二个点时 useEffect 被调用。 另外,如果我在 useEffect 中添加任何其他简单的函数,如 const test = () => console.log('test'),它会在每次安装组件时添加。 只有这些 window.api.receive 函数不会添加和触发。
【问题讨论】: