Skip to content

Instantly share code, notes, and snippets.

@spro
Last active December 23, 2022 09:16
Show Gist options
  • Save spro/280e06758099a05b3bfb6e876e919f2e to your computer and use it in GitHub Desktop.
Save spro/280e06758099a05b3bfb6e876e919f2e to your computer and use it in GitHub Desktop.
Another attempt at SSR with Recoil - setting initial atom values with Next.js getServerSideProps, this time with effects
import {useEffect, useMemo} 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."}
// A potentially dangerous mutable global variable for initial state. The main
// page component will overwrite this when it first mounts (in a useMemo hook),
// given the props passed in by getServerSideProps
let initialRecoilState = null
// Atom effect that reads from initial
const initialEffect = (key) =>
({setSelf}) => {
if ((initialRecoilState != null) && (initialRecoilState[key] != undefined))
setSelf(initialRecoilState[key])
}
// Recoil atom to store user. The default is set to user1, but will be replaced
// with user2 when the effect runs
const userState = atom({
key: 'user',
default: user1,
effects_UNSTABLE: [initialEffect('user')]
})
// 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>
<p><strong className='username'>{user.username}</strong></p>
<p className='bio'>{user.bio}</p>
</div>
}
export async function getServerSideProps() {
return {
props: {
initialRecoilState: {user: user2}
}
}
}
export default function Home(props) {
useMemo(() => {
const context = (typeof window !== 'undefined') ? 'client' : 'server'
console.log(`<${context}> [initialRecoilState]`, props.initialRecoilState)
initialRecoilState = props.initialRecoilState // Overwrite the global mutable variable
}, [])
return (
<RecoilRoot>
<User />
</RecoilRoot>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment