【问题标题】:Functions are getting undefined in a component when component is mounted again. (React+Electron)再次挂载组件时,组件中的功能变得未定义。 (反应+电子)
【发布时间】: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 函数不会添加和触发。

【问题讨论】:

    标签: reactjs electron


    【解决方案1】:

    变量validChannels为空,你应该初始化数组:

    contextBridge.exposeInMainWorld(
        'api', {
            send: (channel, data) => {
                const validChannels = ["projectId", "taskDetails"]; // <=== Initialize this array
                if (validChannels.includes(channel)) {
                    ipcRenderer.send(channel, data)
                }
            },
            receive: (channel, func) => {
                const validChannels = ["projectId", "taskDetails"]; // <=== Initialize this array
                if (validChannels.includes(channel)) {
                    const subscription = (event, ...args) => func(...args)
                    ipcRenderer.on(channel, subscription)
                    return () => {
                        console.log('Removing listener: ', channel)
                        ipcRenderer.removeListener(channel, subscription)
                    }
                }
            }
        }
    )
    

    【讨论】:

    • validChannels 已被所有预期事件填充。立即更新问题。
    猜你喜欢
    • 2014-04-19
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    • 2018-07-02
    • 1970-01-01
    • 2023-03-15
    • 2021-02-24
    • 2019-03-03
    相关资源
    最近更新 更多