Dec 27, 2024
0
Level 2
Laravel Echo in React with Hooks and Providers
Using window in React is not really the React way, better to use Hooks instead. Except, Echo only needs to be instantiated once, thus use Providers and Hooks.
import { useContext, createContext, useEffect, useState, ReactNode } from 'react'
import { EchoContext } from '@/app/(providers)/EchoProvider'
import Pusher from 'pusher-js'
import Echo from 'laravel-echo'
import axios from '@/lib/axios'
const EchoContext = createContext<Echo<'reverb'> | null>(null)
const EchoProvider = ({ children }: Props) => {
const [echo, setEcho] = useState<Echo<'reverb'> | null>(null)
useEffect(() => {
if (!echo) {
setEcho(initEcho())
}
return () => {
if (!echo) return
echo.disconnect()
}
}, [echo])
const initEcho = () => {
return new Echo({
broadcaster: 'reverb',
Pusher: Pusher,
key: process.env.VITE_REVERB_APP_KEY ?? '',
wsHost: process.env.VITE_REVERB_HOST ?? '',
wsPort: process.env.VITE_REVERB_PORT ?? '',
wssPort: process.env.VITE_REVERB_PORT ?? '',
forceTLS: (process.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
authorizer: (channel, options) => ({
authorize: (socketId, callback) => {
axios
.post(`/broadcasting/auth`, {
socket_id: socketId,
channel_name: channel.name,
})
.then(response => {
callback(null, response.data)
})
.catch(error => {
callback(error)
})
},
}),
})
}
return <EchoContext.Provider value={echo}>{children}</EchoContext.Provider>
}
const useEcho = () => {
return useContext(EchoContext)
}
// Layout
const RootLayout = ({ children }) => {
return (
<EchoProvider>
<html lang="en" data-theme="dark">
<body>{children}</body>
</html>
</EchoProvider>
)
}
// Page
const Home = () => {
const echo = useEcho()
useEffect(() => {
console.log('echo', echo)
}, [echo])
return (
<>
<div>
Test Page
</div>
</>
)
}
Since the provider is at the root, all components underneath just need to call useEcho() to get the initial Echo object and do everything you need to do. Similar to using window.Echo except more Reacty.
Please or to participate in this conversation.