0

Running the latest easy-peasy (5.2.0) along with the lates major versions of NextJS (12.1.6) and React (18.1.0) causes easy-peasy to throw an error

TypeError: maybeGetServerSnapshot is not a function` when calling their native `useStoreState`.
export default function Counter() {
> 4 |   const count = useStoreState((state) => state.counter.count);
    |                               ^
  5 |   const increment = useStoreActions((actions) => actions.counter.increment);

After lots of looking I have found no other posts about this issue, although I see similar issues with other storage options like zustand https://github.com/pmndrs/zustand/issues/963, although this seems like a red herring.

The error I am facing seems to be an internal NextJS issue with their storage sync to react from easy-peasy but at the end of the day this error does not return a lot of information and I am pretty stuck.

This example of using NextJS with easy-peasy is referenced in quite a few places, and works great https://codesandbox.io/s/c24rg. However, this project uses the last major version of each project respectively. I have a hard requirement of staying at my specified major version or React and Next. Any insight into this issue would be a lot of help.

Edit 1:

Adding SSR state

export function getServerSideProps() {
    const store = initializeStore()

    const data = ['apple', 'pear', 'orange', 'nuts']
    store.getActions().inventory.setItems(data)

    return {
        props: {
            ssrStoreState: store.getState()
        }
    }
}

Initialize client side state

export default function WrappedApp({ Component, pageProps }) {
    const store = useStore(pageProps.ssrStoreState)

    return (
        <StoreProvider store={store}>
            <Component {...pageProps} />
        </StoreProvider>
    )
}

Use state effect to get data

import { useStoreState, useStoreActions } from "easy-peasy";

export default function Counter() {
  const count = useStoreState((state) => state.counter.count);
  const increment = useStoreActions((actions) => actions.counter.increment);

  return (
    <div style={{ margin: "2rem" }}>
      <h1>Counter</h1>
      <p>value = {count}</p>
      <button onClick={increment}>Increment counter</button>
    </div>
  );
}

Custom store instantiation for SSR to client side synchronization Found in the store/store file


function initStore(preloadedState = initialState) {
    return createStore(
        persist(
            storeModel,
            { allow: ['shop'] }
        ),
        { initialState: preloadedState }
    )
}

export const initializeStore = (preloadedState) => {
    let _store = store ?? initStore(preloadedState)

    // After navigating to a page with an initial Redux state, merge that state
    // with the current state in the store, and create a new store
    if (preloadedState && store) {
        _store = initStore({
            ...store.getState(),
            ...preloadedState,
        })
        // Reset the current store
        store = undefined
    }

    // For SSG and SSR always create a new store
    if (typeof window === 'undefined') return _store
    // Create the store once in the client
    if (!store) store = _store

    return _store
}

export function useStore(initialState) {
    const store = useMemo(() => initializeStore(initialState), [initialState])
    return store
}
  • If you use the same project I referenced above, https://codesandbox.io/s/c24rg and upgrade next/react/easy-peasy to their latest versions you will get this exact same error I posted above – Noah Davidson Mar 17 '23 at 17:52
  • Hi Noah! I'm one of the maintainers of EP, and we got this issue tracked here: https://github.com/ctrlplusb/easy-peasy/issues/822 – JAM Mar 31 '23 at 19:05

1 Answers1

0

SSR does not work properly with easy-peasy@5.x.x and NextJS with React 18.

It is fixed in the latest release of easy-peasy (version 6.0.0).

JAM
  • 6,045
  • 1
  • 32
  • 48