I'm after a bit of patterns guidance. I am writing a React front end (using NextJS) to a back end (based on FeathersJS) that relies on a singleton client object. The client will be needed in many different components up and down the tree, basically to make requests to the server for various things.
In the simple examples online, this client object is managed as a shared global, imported wherever it is needed.
// client.js
import io from 'socket.io-client';
import feathers from '@feathersjs/client';
const socket = io();
const client = feathers();
client.configure(feathers.socketio(socket));
client.configure(feathers.authentication());
export default client;
// consumer somewhere
import client from './client';
client.doStuff()
The problem with this is that the global initialisation interacts badly with webpack and server-side rendering, and in general doing initialisation like this in the global scope feels wrong.
Where would you best put this so that (a) it's initialised early but only on client-side; (b) it's easy to get hold of and use from components up and down the component tree?
One option would obviously be just to manage a global singleton that's initialised on demand when first used:
let client = null;
function getClient() {
global client;
if(client === null) {
// initialise client
}
return client;
}
But I'm wondering if there's a more canonical way in React, e.g. using context?