如何防止 ipcRenderer 监听器的倍增?
How to prevent multiplication of ipcRenderer listenters?
我的 React 应用程序中有一个按钮,每次单击它都需要执行 1 次操作。目前,当点击时,听者似乎成倍增加。
这是我使用的代码的简短示例:
// In App.js
const App = () => {
const buttonHandler = () => {
api.myApi.rendererToMain();
api.myApi.mainToRenderer();
};
return (
<div>
<Button cb={buttonHandler} />
</div>
);
};
// In Button.js
const Button = (props) => {
return (
<button type="button" onClick={ (e) => { props.cb() }}>Send Ping</button>
)
};
// In main.js
ipcMain.on('async', (e, msg) => {
console.log(msg); // print ping
e.reply('async_response', 'pong');
});
// In preload.js
contextBridge.exposeInMainWorld('api', {
myApi: {
rendererToMain: () => {
ipcRenderer.send('async', 'ping');
},
mainToRenderer: () => {
ipcRenderer.on('async_response', (e, msg) => {
console.log(msg);
});
},
},
});
当我 运行 电子应用程序时,我有一个主进程的终端打开,并且 devTools 打开用于渲染器的输出。目前,当按钮被按下 3 次时,结果如下:
// In the browserWindow devTools console
pong
(2)pong
(5)pong
// In the Main process console
ping
ping
ping
所需的输出仅与渲染器控制台不同:
pong
pong
pong
我尝试的解决方案
在对 Whosebug 进行一些研究之后,我第一次尝试自己解决这个问题是尝试删除“async_response”频道的 ipcRenderer 侦听器。执行此操作的所有尝试都导致渲染器控制台中没有输出,并且主进程控制台中的所有 3 个预期 ping。
例如:
// Change made in preload.js
contextBridge.exposeInMainWorld('api', {
myApi: {
rendererToMain: () => {
ipcRenderer.send('async', 'ping');
},
mainToRenderer: () => {
ipcRenderer.on('async_response', (e, msg) => {
console.log(msg); // With below change, this does nothing.
});
// Attempt to remove the listener now?
// Seems to remove the listener before any output logged.
ipcRenderer.removeAllListeners('async_response');
},
},
});
如果有人能帮助我了解在哪里以及如何阻止听众的增加,我将永远感激不已。提前谢谢你。
睡了一觉后,我意识到我的搜索范围太窄了。我发现每次按下按钮时都会额外订阅 ipcRenderer.on()
方法,根据此 post 中的概念:
了解这一点后,我对代码进行了以下更改,以便对 ipcRenderer.on()
方法的调用仅发生一次:
// In App.js
const App = () => {
const buttonHandler = () => {
api.myApi.rendererToMain();
// api.myApi.mainToRenderer(); <- Removed this call to the ipcRenderer.on()
};
return (
<div>
<Button cb={buttonHandler} />
</div>
);
};
// In Button.js
const Button = (props) => {
const callbackHandler = () => {
props.cb();
};
// Subscribe to listener on component construction
api.myApi.mainToRenderer();
return (
<button type="button" onClick={ (e) => { callbackHandler() }}>Send Ping</button>
)
};
这些更改会导致完全符合预期的行为。单击按钮三下后,我在渲染器控制台中看到:
(3)pong
暂时不回答这个问题。我绝对愿意接受有关我的修复和实施的评论。
我的 React 应用程序中有一个按钮,每次单击它都需要执行 1 次操作。目前,当点击时,听者似乎成倍增加。
这是我使用的代码的简短示例:
// In App.js
const App = () => {
const buttonHandler = () => {
api.myApi.rendererToMain();
api.myApi.mainToRenderer();
};
return (
<div>
<Button cb={buttonHandler} />
</div>
);
};
// In Button.js
const Button = (props) => {
return (
<button type="button" onClick={ (e) => { props.cb() }}>Send Ping</button>
)
};
// In main.js
ipcMain.on('async', (e, msg) => {
console.log(msg); // print ping
e.reply('async_response', 'pong');
});
// In preload.js
contextBridge.exposeInMainWorld('api', {
myApi: {
rendererToMain: () => {
ipcRenderer.send('async', 'ping');
},
mainToRenderer: () => {
ipcRenderer.on('async_response', (e, msg) => {
console.log(msg);
});
},
},
});
当我 运行 电子应用程序时,我有一个主进程的终端打开,并且 devTools 打开用于渲染器的输出。目前,当按钮被按下 3 次时,结果如下:
// In the browserWindow devTools console
pong
(2)pong
(5)pong
// In the Main process console
ping
ping
ping
所需的输出仅与渲染器控制台不同:
pong
pong
pong
我尝试的解决方案
在对 Whosebug 进行一些研究之后,我第一次尝试自己解决这个问题是尝试删除“async_response”频道的 ipcRenderer 侦听器。执行此操作的所有尝试都导致渲染器控制台中没有输出,并且主进程控制台中的所有 3 个预期 ping。
例如:
// Change made in preload.js
contextBridge.exposeInMainWorld('api', {
myApi: {
rendererToMain: () => {
ipcRenderer.send('async', 'ping');
},
mainToRenderer: () => {
ipcRenderer.on('async_response', (e, msg) => {
console.log(msg); // With below change, this does nothing.
});
// Attempt to remove the listener now?
// Seems to remove the listener before any output logged.
ipcRenderer.removeAllListeners('async_response');
},
},
});
如果有人能帮助我了解在哪里以及如何阻止听众的增加,我将永远感激不已。提前谢谢你。
睡了一觉后,我意识到我的搜索范围太窄了。我发现每次按下按钮时都会额外订阅 ipcRenderer.on()
方法,根据此 post 中的概念:
了解这一点后,我对代码进行了以下更改,以便对 ipcRenderer.on()
方法的调用仅发生一次:
// In App.js
const App = () => {
const buttonHandler = () => {
api.myApi.rendererToMain();
// api.myApi.mainToRenderer(); <- Removed this call to the ipcRenderer.on()
};
return (
<div>
<Button cb={buttonHandler} />
</div>
);
};
// In Button.js
const Button = (props) => {
const callbackHandler = () => {
props.cb();
};
// Subscribe to listener on component construction
api.myApi.mainToRenderer();
return (
<button type="button" onClick={ (e) => { callbackHandler() }}>Send Ping</button>
)
};
这些更改会导致完全符合预期的行为。单击按钮三下后,我在渲染器控制台中看到:
(3)pong
暂时不回答这个问题。我绝对愿意接受有关我的修复和实施的评论。