I am working on a React Native mobile chat application utilizing laravel-echo library for socket connections.
I have a function based EchoServer component, rendered from a custom header component on every page. It calls handleNewMessage through useEffect hook and sets a new Echo object for listening to sockets.
let echo = new Echo({
broadcaster: 'socket.io',
client: socketio,
authEndpoint: constants.echoServer + '/broadcasting/auth',
host: constants.echoServer + ':' + constants.echoServerPort,
auth: {
headers: {
Accept: "application/json",
Authorization: `Bearer ${params.access_token}`,
}
},
});
echo
.private(channel)
.notification((notification) => {
handleNewMessage(notification);
});
console.log('Join "online" channel');
echo.join('online')
.here(users => {
if(users.find(data => data.id === params.user.id)) {
setState({
icon: ICONS.online,
color: COLORS.online
});
}
});
echo.connector.socket.on('subscription_error', (channel, data) => {
console.log('channel subscription error: ' + channel, data);
});
I do not have any issues with listening notifications from the socket connection. However, since this component is rendered in a header component as mentioned above, it also creates a new connection every time the header is rendered. That causes same notifications to come multiple times increasingly (At first I receive 1 notification, then 2 and 3 etc.)
I solved that problem by using a useContext hook for the echo object. I basically used the useContext hook as a global variable.
After,
const [ socket, setSocket ] = useContext(SocketContext);
I check if socket already has a value or not, before creating a "new Echo" object.
if (socket){
return;
}
However, with this solution I had to add another context in my parent App.js file such that:
<AuthContext.Provider value={authContext}>
<SocketContext.Provider value={[socket, setSocket]}>
<MessageStore>
<NavigationContainer>
{ user.access_token?
<MenuStack/>
:
<AuthStack/>
}
</NavigationContainer>
</MessageStore>
</SocketContext.Provider>
</AuthContext.Provider>
I can see that nested contexts might be an issue in future (if they're not already) as I already have 3. What I'd like to ask is, is there a better solution in order to check if socket connection has been established without using useContext hook?
I was also thinking maybe useContext is not the best solution for this.
Also establishing the socket connection right after the authentication process only once might be a better solution, instead of checking it every time in the header.
I am looking for suggestions about the best practices for this case.
Thank you for your helps in advance.