Skip to content

Instantly share code, notes, and snippets.

@alexgriff
Created March 13, 2019 02:29
Show Gist options
  • Save alexgriff/7872ce828c867a1cc5f4e946e61f1998 to your computer and use it in GitHub Desktop.
Save alexgriff/7872ce828c867a1cc5f4e946e61f1998 to your computer and use it in GitHub Desktop.
DIY Socket Provider
// 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