【问题标题】:How to update react state when using contextBridge/preload in electron app在电子应用程序中使用 contextBridge/preload 时如何更新反应状态
【发布时间】:2021-08-25 05:03:55
【问题描述】:

我有一个使用 react 的电子应用程序。我在 preload.js 中使用 contextBridge。我想通过桥将 app.js 中的变量传递给主进程中的函数;它将一个值返回到桥并返回到 app.js,它会以某种方式更新状态并触发重新渲染。以下代码正在工作到更新状态。我不明白如何从 preload.js 到 app.js 获取变量?我希望的临时技巧是从预加载设置 localstorage 并调用 setTimeout 函数来观察特定变量的变化。我知道这是一种不太有趣的方法。代码在这里:

app.js -

async function createSpreadsheet() {
  let x = await electron.google.createSpreadsheetFiles(sheetFileName)
}

preload.js -

const { ipcRenderer, contextBridge, net } = require('electron');

contextBridge.exposeInMainWorld('electron', {
  google: {
    createSpreadsheetFiles(name) {
      ipcRenderer.send('gCreateSpreadSheetFile', name);
      let x = ipcRenderer.on('gCreateSpreadSheetFile-return', function (event, arg) {
      })
      return x
    },
  },
})

main.js -

  ipcMain.on('gCreateSpreadSheetFile', (event, name) => {
    async function all() {
      let resp = await g.createSheetFile(name, win)
      event.sender.send('gCreateSpreadSheetFile-return', resp)
    }
    all()
  })

【问题讨论】:

    标签: reactjs electron ipcrenderer ipcmain


    【解决方案1】:

    您可以使用 ipcRenderer 调用和 ipcMain 句柄:

    preload.js

    contextBridge.exposeInMainWorld('electron', {
      google: {
        createSpreadsheetFiles: (name) => ipcRenderer.invoke('gCreateSpreadSheetFile-invoke', name),
      },
    });
    

    main.js

    ipcMain.handle('gCreateSpreadSheetFile-invoke', (event, name) => {
      return 'value';
    });
    

    renderer

    window.electron.google.createSpreadsheetFiles(spreadSheetName).then((value) => {
      console.log(value);
    });
    // or
    var value = await window.electron.google.createSpreadsheetFiles(spreadSheetName);
    

    关于文档:https://www.electronjs.org/docs/api/ipc-renderer#ipcrendererinvokechannel-args

    【讨论】:

    • 感谢您的回复。
    • 好的,我为过早接受而道歉。我已经尝试了您的代码,但我仍然不知道如何从 preload.js 返回到 app.js。我确定这是一个语法问题,或者我不明白预加载的返回。如果你有时间,你可以看看我在下面写的代码。谢谢
    • 对不起,我没有测试代码,我会测试它,看看我是否可以修复它。我可能搞砸了,因为这种方法过去对我很有效。
    • 好吧,我终于回到了这个话题。此语法对我有用,我将您的答案标记为正确。
    【解决方案2】:

    好的,我很抱歉在答案部分发布另一个问题,我不明白如何在评论响应中格式化代码。

    这段代码仍然不会返回到 app.js:

    app.js    
    
    const res = await electron.g.createSpreadsheetFiles(sheetFileName)
            console.log(res) // prints undefined, before code is excecuted
    

    返回 res 而不等待 preload.js 的返回。这是来自 preload.js 的代码

    preload.js    
    
    g: {
            createSpreadsheetFiles(name) {
              (async () => {
                const result = await ipcRenderer.invoke('gCreateSpreadSheetFile-invoke',  name);
                return result; 
              })();
          }
    

    【讨论】:

    • 我已经更新了我的答案,使其更加清晰。顺便说一下preload.js文件是多余的,使用createSpreadsheetFiles: (name) => ipcRenderer.invoke('gCreateSpreadSheetFile-invoke', name);会有同样的效果,而在app.js中你应该使用window.electron.g...
    猜你喜欢
    • 1970-01-01
    • 2021-01-06
    • 2017-11-09
    • 2019-04-29
    • 2019-08-29
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    相关资源
    最近更新 更多