I have an Electron app with include (among others) the following files:
index.js
browserwindow.html
browserwindow.js
(which get compiled from browserwindow.jsx
)index.js
is the main Electron/Node process that runs when the Electron app is started. browserwindow.html
is rendered in the guiWindow
, browserwindow.js
manages this window. (See the files below.)
What I want, is to send an ipc message from the main Electron proccess to browserwindow.js
, which then updates the React component state. But when I use the code in the files below and run the Electron app, the state does not change.
index.js
const electron = require('electron');
const BrowserWindow = electron.BrowserWindow;
const app = electron.app;
const url = require('url');
const ipc = electron.ipcMain;
app.on('ready', function(){
// Make window
var guiWindow;
// Set size and do not immediately show
guiWindow = new BrowserWindow({
width: 800,
height: 780,
show: false
});
// Load browserwindow.html in the guiWindow
guiWindow.loadURL('file://' + __dirname + '/browserwindow.html');
// Show the window when the .html file is loaded
guiWindow.once('ready-to-show', function(){
guiWindow.show();
});
// Send an ipc after 3 seconds
setInterval(function(){
guiWindow.webContents.send('message', {msg: 'Hello World!'});
}, 3000);
});
browserwindow.html
<!DOCTYPE html>
<html>
<head>
<title>Page</title>
</head>
<body>
<!-- The div that React uses: -->
<div id="mainInterface"></div>
<script src="react-0.14.3.js"></script>
<script src="react-dom-0.14.3.js"></script>
<script src="browserwindow.js"></script>
</body>
</html>
jsx that gets compiled to browserwindow.js
var electron = require('electron');
var shell = electron.shell;
var ipc = electron.ipcRenderer;
class MainInterface extends React.Component {
constructor(props, contect){
super(props);
this.state = {
testValue: 'Initial state'
};
};
componentDidMount(){ // When the document is rendered
ipc.on('message', function(event, data){ // When the message is received...
console.log('Message received');
this.setState({testValue: 'It worked!'}); // ... change the state of this React component
});
}
render(){
return (
<h1>{ this.state.testValue }</h1>
);
}
}
ReactDOM.render(
<MainInterface />,
document.getElementById('mainInterface')
);
In the Javascript console, I get the following error:
Uncaught TypeError: this.setState is not a function
at EventEmitter.<anonymous> (file:///C:/Users/<file path to the project on my computer>/testproject/browserwindow.js:20:12)
at emitTwo (events.js:106:13)
at EventEmitter.emit (events.js:194:7)
What can I do to fix this issue?
(For some background, I am making an Electron app that should receives messages over MQTT and update the elements on the screen based on the received message.)
Your this
points to the different context than component really is. You need to change your code to
componentDidMount() {
// When the document is rendered.
const self = this;
ipc.on('message', function (event, data) {
// When the message is received...
console.log('Message received');
// ... change the state of this React component.
self.setState({testValue: 'It worked!'});
});
}
Or you may replace function()
callback by () => {}
because the first option changes the context of the execution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With