-
-
Save alexgriff/7872ce828c867a1cc5f4e946e61f1998 to your computer and use it in GitHub Desktop.
DIY Socket Provider
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// this uses the vanilla js actioncable package https://www.npmjs.com/package/actioncable | |
// and makes it useable for react components | |
// STEP 1 | |
// Create the context | |
// socketContext.js | |
import { createContext } from 'react' | |
const SocketContext = createContext() | |
export default SocketContext | |
// STEP 2 | |
// Create the Provider | |
// this component will be rendered one time wrapping the app (like the redux provider) | |
// it's job is to establish the socket connection and stick the object into the context | |
// SocketProvider.js | |
import React from 'react' | |
import SocketContext from './socketContext' | |
import ActionCable from 'actioncable' | |
class SocketProvider extends React.Component { | |
state = {} | |
componentDidMount() { | |
const connection = ActionCable.createConsumer(this.props.wsUrl) | |
this.setState({ connection }) | |
} | |
render() { | |
return ( | |
<SocketContext.Provider value={this.state.connection}> | |
{ this.props.children } | |
</SocketContext.Provider> | |
) | |
} | |
} | |
export default SocketProvider | |
// STEP 3: | |
// Create the Socket Channel / Consumer component | |
// it's job is to access the socket connection from the context | |
// and let you register a callback to be invoked when a message is received | |
// on the right channel. | |
// Using this component does not change the markup of whatever it's parent is, it | |
// only allows you to respond to broadcasted messages | |
// SocketConsumer.js | |
import React from 'react' | |
import SocketContext from './socketContext' | |
class SocketChannel extends React.Component { | |
componentDidMount() { | |
const { socket, channel, id, onMessage } = this.props | |
socket.subscriptions.create({ channel, id }, { | |
received: onMessage | |
}) | |
} | |
render() { | |
return null | |
} | |
} | |
export default ({channel, id, onMessage}) => ( | |
<SocketContext.Consumer> | |
{ | |
socket => ( | |
<SocketChannel socket={socket} channel={channel} id={id} onMessage={onMessage} /> | |
) | |
} | |
</SocketContext.Consumer> | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment