Last active
March 25, 2024 15:05
-
-
Save optilude/2bb137fff73651e469d96825fa0c5861 to your computer and use it in GitHub Desktop.
Pattern for accessing a Feathers client via a React context hook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
is this pattern tested and working?