使用 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 状态。
注意:我是这个插件的作者。
我正在尝试 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 状态。
注意:我是这个插件的作者。