diff --git a/examples/with-pullstate/.gitignore b/examples/with-pullstate/.gitignore new file mode 100644 index 0000000000000..1437c53f70bc2 --- /dev/null +++ b/examples/with-pullstate/.gitignore @@ -0,0 +1,34 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel diff --git a/examples/with-pullstate/README.md b/examples/with-pullstate/README.md new file mode 100644 index 0000000000000..07b9bbba0a1d2 --- /dev/null +++ b/examples/with-pullstate/README.md @@ -0,0 +1,23 @@ +# Pullstate example + +This example shows how to integrate Pullstate in Next.js. + +In the example we are going to display how to toggle dark mode using the store from pullstate. + +## Deploy your own + +Deploy the example using [Vercel](https://vercel.com): + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/vercel/next.js/tree/canary/examples/with-pullstate) + +## How to use + +Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: + +```bash +npx create-next-app --example with-pullstate with-pullstate-app +# or +yarn create next-app --example with-pullstate with-pullstate-app +``` + +Deploy it to the cloud with [Vercel](https://vercel.com/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). diff --git a/examples/with-pullstate/components/dark-mode-demo.js b/examples/with-pullstate/components/dark-mode-demo.js new file mode 100644 index 0000000000000..d2e70322a572e --- /dev/null +++ b/examples/with-pullstate/components/dark-mode-demo.js @@ -0,0 +1,29 @@ +import { PullstateCore } from '../stores' + +export default function DarkModeDemo() { + const { UIStore } = PullstateCore.useStores() + const isDarkMode = UIStore.useState((s) => s.isDarkMode) + + return ( +
+

Pullstate Demo

+ +

Dark Mode is {isDarkMode ? 'On' : 'Off'}

+ + +
+ ) +} diff --git a/examples/with-pullstate/package.json b/examples/with-pullstate/package.json new file mode 100644 index 0000000000000..35fc09731c8e5 --- /dev/null +++ b/examples/with-pullstate/package.json @@ -0,0 +1,16 @@ +{ + "name": "with-pullstate", + "version": "1.0.0", + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "next": "latest", + "pullstate": "1.20.4", + "react": "^16.9.0", + "react-dom": "^16.9.0" + }, + "license": "MIT" +} diff --git a/examples/with-pullstate/pages/_app.js b/examples/with-pullstate/pages/_app.js new file mode 100644 index 0000000000000..e680cf23c0389 --- /dev/null +++ b/examples/with-pullstate/pages/_app.js @@ -0,0 +1,13 @@ +import { PullstateProvider } from 'pullstate' + +import { useHydrate } from '../stores' + +export default function App({ Component, pageProps }) { + const instance = useHydrate(pageProps.snapshot) + + return ( + + + + ) +} diff --git a/examples/with-pullstate/pages/index.js b/examples/with-pullstate/pages/index.js new file mode 100644 index 0000000000000..24a44083edd88 --- /dev/null +++ b/examples/with-pullstate/pages/index.js @@ -0,0 +1,5 @@ +import DarkModeDemo from '../components/dark-mode-demo' + +export default function Home() { + return +} diff --git a/examples/with-pullstate/pages/ssg.js b/examples/with-pullstate/pages/ssg.js new file mode 100644 index 0000000000000..c343762c1c40b --- /dev/null +++ b/examples/with-pullstate/pages/ssg.js @@ -0,0 +1,25 @@ +import DarkModeDemo from '../components/dark-mode-demo' + +export default function SSG() { + return +} + +export async function getStaticProps() { + const instance = PullstateCore.instantiate() + + // Example of fetching data from some api + const preferences = await new Promise((resolve) => + resolve({ isDarkMode: false }) + ) + + // Update the store on the server before page render + instance.stores.UIStore.update((s) => { + s.isDarkMode = preferences.isDarkMode + }) + + return { + props: { + snapshot: JSON.stringify(instance.getPullstateSnapshot()), + }, + } +} diff --git a/examples/with-pullstate/pages/ssr.js b/examples/with-pullstate/pages/ssr.js new file mode 100644 index 0000000000000..fe51f5a9f74a7 --- /dev/null +++ b/examples/with-pullstate/pages/ssr.js @@ -0,0 +1,26 @@ +import DarkModeDemo from '../components/dark-mode-demo' +import { PullstateCore } from '../stores' + +export default function SSR() { + return +} + +export async function getServerSideProps() { + const instance = PullstateCore.instantiate({ ssr: true }) + + // Example of fetching data from some api + const preferences = await new Promise((resolve) => + resolve({ isDarkMode: false }) + ) + + // Update the store on the server before page load + instance.stores.UIStore.update((s) => { + s.isDarkMode = preferences.isDarkMode + }) + + return { + props: { + snapshot: JSON.stringify(instance.getPullstateSnapshot()), + }, + } +} diff --git a/examples/with-pullstate/stores/index.js b/examples/with-pullstate/stores/index.js new file mode 100644 index 0000000000000..45aec161d10d8 --- /dev/null +++ b/examples/with-pullstate/stores/index.js @@ -0,0 +1,15 @@ +import { createPullstateCore } from 'pullstate' +import { useMemo } from 'react' + +import { UIStore } from './ui' + +export const PullstateCore = createPullstateCore({ + UIStore, +}) + +export function useHydrate(snapshot) { + return useMemo(() => { + if (!snapshot) return PullstateCore.instantiate() + return PullstateCore.instantiate({ hydrateSnapshot: JSON.parse(snapshot) }) + }, [snapshot]) +} diff --git a/examples/with-pullstate/stores/ui.js b/examples/with-pullstate/stores/ui.js new file mode 100644 index 0000000000000..f5e25a73f533b --- /dev/null +++ b/examples/with-pullstate/stores/ui.js @@ -0,0 +1,3 @@ +import { Store } from 'pullstate' + +export const UIStore = new Store({ isDarkMode: true })