使用 React、Redux、Electron 将函数传递给 ipcMain 并返回的解决方法

Workaround for passing function to ipcMain and back using React, Redux, Electron

我正在尝试 load/update 在我的应用程序中的特定时间从本地数据库文件获取数据。这个文件当然必须从主进程访问,所以我从渲染器发送到主进程,然后当主进程 returns 我需要的数据时,我需要 运行 Redux 的调度来更新我的据此说明。问题是我的 ipcRenderer.on() 侦听器没有上下文来正确调用调度。我尝试将一个函数传递给主进程,然后返回给渲染器,但是函数从 ipcRenderer.send.

中被剥离

一旦我从主进程接收到返回的数据,我该如何正确地更新我的状态?在我的代码的孤立块下面。

主要流程:

ipcMain.on('getSites', (event, args) => {
  db.sites.find({}, (err, docs) => {
    event.sender.send('getSitesSuccess', { data: docs, dispatch: args.dispatch });
  });
});

渲染器进程:

ipcRenderer.on('getSitesSuccess', (event, args) => {
  args.dispatch(args.data);
});

class SiteList extends Component {
  componentWillMount() {
    ipcRenderer.send('getSites', {
      test: 'test',
      dispatch: (data) => { this.props.dispatch(actions.change('sites', data)); }
    });
  }
}

我不确定这是否是最佳方法,但事实证明,对我的代码进行一些重构是解决方案。我不需要将 ipcRenderer.on 放在组件外部,只需将它嵌套在组件的构造函数中即可。希望这对以后的人有帮助。

class SiteList extends Component {
  constructor(props, context) {
    super(props, context);

    ipcRenderer.on('getSitesSuccess', (event, args) => {
      console.log('data', args.data);
      props.dispatch(actions.change('sites', args.data));
    });
  }
}

确保在 class 实例 (componentDidMount) 中设置事件侦听器。此外,确保在实例处理后正确处理任何事件侦听器 (componentWillUnmount)。

class SiteList extends Component {
  componentDidMount() {
    ipcRenderer.on('getSitesSuccess', this.handleSitesSuccess);
  }

  componentWillUnmount() {
    ipcRenderer.removeListener('getSitesSuccess', this.handleSitesSuccess);
  }

  handleSitesSuccess(event, args) {
    console.log('data', args.data);
    props.dispatch(actions.change('sites', args.data));
  }
}

如果您正在进行大量 ipc 调用(接收和发送),请查看 redux-electron-ipc (link)。这从您的实际组件中删除了 ipc 调用的连接逻辑,并让您直接使用 redux 状态。

注意:我是这个插件的作者。