Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update useWeb3Store.ts #92

Open
wants to merge 1 commit into
base: trunk
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 82 additions & 2 deletions hooks/useWeb3Store.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
/**
* @constant State
* @since 0.7.0
* @since 0.8.0
*/
import type MetaMaskConnector from '@/lib/connectors/metamask';
import type WalletConnectConnector from '@/lib/connectors/walletconnect';
import type { Web3Provider } from '@ethersproject/providers';
import create from 'zustand';
import { omit } from 'omit-ts';
import { useLayoutEffect } from 'react'

import createContext from 'zustand/context'

let store

//const getDefaultInitialState = () => ({
//lastUpdate: Date.now(),
//light: false,
//count: 0,
//})

const zustandContext = createContext()

export const Provider = zustandContext.Provider
// An example of how to get types
/** @type {import('zustand/index').UseStore<typeof initialState>} */
export const useStore = zustandContext.useStore

export type State = {
account?: string;
Expand All @@ -18,16 +36,78 @@ export type State = {
};

const useWeb3Store = create<State>((set, get) => ({
/*
...getDefaultInitialState(),
...preloadedState,
tick: (lastUpdate, tx) => {
set({
lastUpdate,
tx: !!mined,
})
},
increment: () => {
set({
status: get().count + 1,
})
},
decrement: () => {
set({
status: get().count - 1,
})
},
*/
active:
get()?.connector !== undefined &&
get()?.chainId !== undefined &&
get()?.account !== undefined,
reset: () =>
set(
//{
(state) => omit(state, ['account', 'chainId', 'connector', 'library']),
true,
),
// web3: getDefaultInitialState().web3
//}
),
}));

export function useCreateStore(serverInitialState) {
// Server side code: For SSR & SSG, always use a new store.
if (typeof window === 'undefined') {
return () => initializeStore(serverInitialState)
}
// End of server side code

// Client side code:
// Next.js always re-uses same store regardless of whether page is a SSR or SSG or CSR type.
const isReusingStore = Boolean(store)
store = store ?? initializeStore(serverInitialState)
// When next.js re-renders _app while re-using an older store, then replace current state with
// the new state (in the next render cycle).
// (Why next render cycle? Because react cannot re-render while a render is already in progress.
// i.e. we cannot do a setState() as that will initiate a re-render)
//
// eslint complaining "React Hooks must be called in the exact same order in every component render"
// is ignorable as this code runs in same order in a given environment (i.e. client or server)
// eslint-disable-next-line react-hooks/rules-of-hooks
useLayoutEffect(() => {
// serverInitialState is undefined for CSR pages. It is up to you if you want to reset
// states on CSR page navigation or not. I have chosen not to, but if you choose to,
// then add `serverInitialState = getDefaultInitialState()` here.
if (serverInitialState && isReusingStore) {
store.setState(
{
// re-use functions from existing store
...store.getState(),
// but reset all other properties.
...serverInitialState,
},
true // replace states, rather than shallow merging
)
}
})

return () => store
}

export default useWeb3Store;
/** @export useWeb3Store */