Skip to content

Instantly share code, notes, and snippets.

@optilude
Last active March 25, 2024 15:05
Show Gist options
  • Save optilude/2bb137fff73651e469d96825fa0c5861 to your computer and use it in GitHub Desktop.
Save optilude/2bb137fff73651e469d96825fa0c5861 to your computer and use it in GitHub Desktop.
Pattern for accessing a Feathers client via a React context hook
import React, { useState, useEffect } from 'react';
import { FeathersContext, createFeathersClient } from '../feathersClient';
/**
* Top level app wrapper which does a few things:
*
* - Ensure the feathers context is set up, so that pages can just `useFeathers()` to get a client.
* - Listen for login/logout events and pass a `user` prop to pages which is either `null`, or a user object.
*/
export default function App({Component, pageProps}) {
let [client] = useState(() => createFeathersClient());
let [user, setUser] = useState(null);
// set/unset `user` state variable based one vents
useEffect(() => {
client.on('authenticated', login => {
setUser(login);
});
client.on('logout', () => {
setUser(null);
});
}, []);
// attempt to re-authenticate once when component is mounted
useEffect(() => {
client.reAuthenticate().catch(() => {
setUser(null);
// TODO: Could redirect to login page, for example
});
}, []);
return (
<FeathersContext.Provider value={client}>
<Component user={user} {...pageProps} />
</FeathersContext.Provider>
);
}
import React, { useContext } from 'react';
import feathers from '@feathersjs/client';
import io from 'socket.io-client';
export const FeathersContext = React.createContext(null);
export function createFeathersClient() {
const socket = io();
let client = feathers();
client.configure(feathers.socketio(socket));
client.configure(feathers.authentication({
// can happen on server-side rendering, but we don't authenticate then anyway
storage: typeof window == 'undefined'? null : window.localStorage
}));
return client;
}
export function useFeathers() {
return useContext(FeathersContext);
}
import Layout from '../components/Layout';
import { useFeathers } from '../feathersClient';
export default function Index({ user }) {
const client = useFeathers();
return (
<Layout>
<h1>NextJS test</h1>
<p>{user? user.user.email : "not logged in"}</p>
<button onClick={client.logout}>Log out</button>
</Layout>
);
}
@Zw1d
Copy link

Zw1d commented Mar 25, 2024

Hi,
is this pattern tested and working?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment