Skip to content

Instantly share code, notes, and snippets.

@nursarowar
Forked from spro/next-ssr-recoil.js
Created February 7, 2022 14:23
Show Gist options
  • Save nursarowar/686b630befa0f584a21a76e742c9228e to your computer and use it in GitHub Desktop.
Save nursarowar/686b630befa0f584a21a76e742c9228e to your computer and use it in GitHub Desktop.
Attempt at SSR with Recoil - setting initial atom values with Next.js getServerSideProps
import {useEffect} from 'react'
import {RecoilRoot, useRecoilState, atom} from 'recoil'
// User data
const user1 = {username: 'joe', bio: "You will never see me, unless of course this example is totally broken."}
const user2 = {username: 'bob', bio: "I am the one true user."}
const user3 = {username: 'fred', bio: "Just kidding, make way for the new guy."}
// Recoil atom to store user. The default user is user1, but it will be
// replaced when the root state is initialized
const userState = atom({
key: 'user',
default: user1
})
// Keep a reference to all atoms by key for initializeRecoilState
const all_atoms = {
user: userState
}
// Where the magic happens: Used by RecoilRoot to update atoms by key given an
// initial state object of the form {key: initial_value}
const initializeRecoilState = (initialRecoilState) => ({set}) =>
Object.keys(initialRecoilState).map((key) => {
const value = initialRecoilState[key]
const atom = all_atoms[key]
set(atom, value)
})
// Component to display user info
function User() {
const [user, setUser] = useRecoilState(userState)
// Show recoil is alive by setting to user3 after a bit
useEffect(() =>
setTimeout(() => setUser(user3), 2000)
, [])
return <div>
<strong className='username'>{user.username}</strong>
<p className='bio'>{user.bio}</p>
</div>
}
// Faux SSR "loading" user2 into the initial state
export async function getServerSideProps() {
const initialRecoilState = {
user: user2
}
console.log("Created initial Recoil state:", initialRecoilState)
return {
props: {initialRecoilState}
}
}
export default function Home({initialRecoilState={}}) {
console.log('Rendering with initial Recoil state:', initialRecoilState)
return (
<RecoilRoot initializeState={initializeRecoilState(initialRecoilState)}>
<User />
</RecoilRoot>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment