So I have a react app, I want to include a file for websockets (currently a class) but I want to be able to call things in App from it (when the WS provides messages). I'm looking for something like a react callback prop, but I don't think using a component is necessary since this class will not render anything.
Whats the best way to implement this?
class App extends React.Component {
constructor() {
super()
this.ws = undefined;
}
sendMessage(data) {
console.log(data)
}
connect = () => {
this.ws = new Websocket();
};
render() {
return <div>
<button onClick={this.connect}>Connect</button>
</div>
}
}
let ws = new WebSocket("ws://localhost:8080/");
export default class Websocket {
componentDidMount() {
ws.addEventListener("message", this.getPosition);
}
componentWillUnmount() {
ws.removeEventListener("message", this.getPosition);
}
giveData = ({data}) => {
//here I want to send the data to sendMessage in App component
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
You can use a class to create multiple instances of a WebSocket connection if you'd like, but
I'm looking for something like a react callback prop
not sure what you mean by that, but if you want to pass a callback function to be called when the ws instance gets a message you could instead pass the callback to the WebSocket class in the constructor.
Let's say this is your Websocket in the file Websocket.js
export default class Websocket {
constructor(onMessage) {
// onMessage is expected to be a callback function
this.ws = new WebSocket("wss://<url>");
this.onMessage = onMessage;
// add the event listener using the custom callback you pass in constructor
this.ws.addEventListener("message", this.onMessage);
}
// when closing the connection to make sure to remove the event listener
closeConnection = () => {
// as a cleanup you should call this in your `componentWillUnmount` hook, which will clear the event listeners,
// in order to prevent memory leaks
this.ws.removeEventListener("message", this.onMessage);
this.ws.close();
};
// incase you need to reopen the connection
openConnection = () => {
// if connection is already open or connecting
if (
this.ws.readyState === this.ws.OPEN ||
this.ws.readyState === this.ws.CONNECTING
)
return;
this.ws.addEventListener("message", this.onMessage);
};
Now, in your App component, you can just pass the function you want to be called when message is received like so
export default class App extends Component {
constructor() {
super()
this.ws = null;
}
sendMessage(data) {
console.log(data);
}
connect = () => {
// pass sendMessage to be used when receiving socket messages in the constructor
this.ws = new Websocket(this.sendMessage);
};
// cleanup to ensure eventListeners are cleared
componentWillUnmount = () => {
this.ws.closeConnection();
}
render() {
return (
<div>
<button onClick={this.connect}>Connect</button>
</div>
)
}
}