Last active
December 23, 2022 09:16
-
-
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
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 {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