From 0e8bb5487f22167db1e63261c3a1efff1d86ca7b Mon Sep 17 00:00:00 2001 From: Simon Wicki Date: Thu, 16 Sep 2021 14:14:20 +0200 Subject: [PATCH] fix: use CSR for dev and prod, use localStorage as state storage --- ui/packages/app/web/src/components/NoSSR.tsx | 5 +++ ui/packages/app/web/src/pages/_app.tsx | 27 +++++++------- ui/packages/app/web/src/pages/index.tsx | 2 +- .../app/web/src/store/cookie-storage.ts | 15 -------- ui/packages/app/web/src/store/index.ts | 36 +++++-------------- ui/packages/app/web/src/store/noop-storage.ts | 8 ----- 6 files changed, 28 insertions(+), 65 deletions(-) create mode 100644 ui/packages/app/web/src/components/NoSSR.tsx delete mode 100644 ui/packages/app/web/src/store/cookie-storage.ts delete mode 100644 ui/packages/app/web/src/store/noop-storage.ts diff --git a/ui/packages/app/web/src/components/NoSSR.tsx b/ui/packages/app/web/src/components/NoSSR.tsx new file mode 100644 index 00000000000..892e34b51cf --- /dev/null +++ b/ui/packages/app/web/src/components/NoSSR.tsx @@ -0,0 +1,5 @@ +// simple wrapper that needs to be imported via next/dynamic. +// this way we CSR the app in dev like in prod (SSG'd). +const NoSSR = ({ children }) => <>{children} + +export default NoSSR diff --git a/ui/packages/app/web/src/pages/_app.tsx b/ui/packages/app/web/src/pages/_app.tsx index b864a2e52c1..e6480d2a452 100644 --- a/ui/packages/app/web/src/pages/_app.tsx +++ b/ui/packages/app/web/src/pages/_app.tsx @@ -1,3 +1,4 @@ +import dynamic from 'next/dynamic' import { Container } from 'react-bootstrap' import 'react-dates/lib/css/_datepicker.css' import { StoreProvider, useCreateStore } from 'store' @@ -10,22 +11,22 @@ import './App.scss' import Header from './layouts/Header' import ThemeProvider from './layouts/ThemeProvider' +const NoSSR = dynamic(() => import('../components/NoSSR'), { ssr: false }) + const App = ({ Component, pageProps }) => { - const { persistedState } = pageProps - // this is only point where persisted state can come in. it's either from: - // - cookies headers (server) - // - window.__NEXT_DATA__ (client) - const createStore = useCreateStore(persistedState?.state) + const createStore = useCreateStore() return ( - - -
- - - - - + + + +
+ + + + + + ) } diff --git a/ui/packages/app/web/src/pages/index.tsx b/ui/packages/app/web/src/pages/index.tsx index e25f4646c3b..19bcd7880dc 100644 --- a/ui/packages/app/web/src/pages/index.tsx +++ b/ui/packages/app/web/src/pages/index.tsx @@ -1,6 +1,6 @@ +import { QueryServiceClient } from '@parca/client' import ProfileExplorer from 'components/ProfileExplorer' import { NextRouter, withRouter } from 'next/router' -import { QueryServiceClient } from '@parca/client' const apiEndpoint = process.env.NEXT_PUBLIC_API_ENDPOINT diff --git a/ui/packages/app/web/src/store/cookie-storage.ts b/ui/packages/app/web/src/store/cookie-storage.ts deleted file mode 100644 index f11270e2afb..00000000000 --- a/ui/packages/app/web/src/store/cookie-storage.ts +++ /dev/null @@ -1,15 +0,0 @@ -import Cookies from 'universal-cookie' -import { StateStorage } from 'zustand/middleware' - -const cookie = new Cookies() - -const CookieStorage: StateStorage = { - setItem: (key, value) => { - cookie.set(key, value) - }, - getItem: key => { - return cookie.get(key) - } -} - -export default CookieStorage diff --git a/ui/packages/app/web/src/store/index.ts b/ui/packages/app/web/src/store/index.ts index 083870152cb..e69a224fbc6 100644 --- a/ui/packages/app/web/src/store/index.ts +++ b/ui/packages/app/web/src/store/index.ts @@ -1,9 +1,6 @@ -import { useLayoutEffect } from 'react' import create from 'zustand' import createContext from 'zustand/context' import { persist } from 'zustand/middleware' -import CookieStorage from './cookie-storage' -import NoopStorage from './noop-storage' import createUiState from './ui.state' let store @@ -23,40 +20,23 @@ export const StoreProvider = zustandContext.Provider export const useStore = zustandContext.useStore -export const initializeStore = (initialState = {}) => { +export const initializeStore = () => { return create( - persist( - (set, get) => ({ - ...stateSlices(set, get), - ...initialState - }), - { - name: 'parca', - whitelist: whitelistPersist, - getStorage: () => (typeof document !== 'undefined' ? CookieStorage : NoopStorage) - } - ) + persist((set, get) => stateSlices(set, get), { + name: 'parca', + whitelist: whitelistPersist + }) ) } -export function useCreateStore(initialState) { +export function useCreateStore() { // For SSR & SSG, always use a new store. if (typeof window === 'undefined') { - return () => initializeStore(initialState) + return () => initializeStore() } // For CSR, always re-use same store. - store = store ?? initializeStore(initialState) - // And if initialState changes, then merge states in the next render cycle. - // @todo does initialState ever change? - useLayoutEffect(() => { - if (initialState && store) { - store.setState({ - ...store.getState(), - ...initialState - }) - } - }, [initialState]) + store = store ?? initializeStore() return () => store } diff --git a/ui/packages/app/web/src/store/noop-storage.ts b/ui/packages/app/web/src/store/noop-storage.ts deleted file mode 100644 index 2642b237b95..00000000000 --- a/ui/packages/app/web/src/store/noop-storage.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { StateStorage } from 'zustand/middleware' - -const NoopStorage: StateStorage = { - setItem: (_key, _value) => {}, - getItem: key => key -} - -export default NoopStorage