0

Hello Stackoverflow Community,

I was hoping you could help me with the following logic. I would like to return from a custom-built hook the last item the user selected in a onClick function.

const useActiveWeb3React = (): Web3ReactContextInterface<Web3Provider> => {
  const { chainId, account, ...web3React } = useWeb3React()
  const { solanaAccount, solanaChainId } = useSolanaWeb3React()

  const activeChain = "if the user's last selected chain is Solana" ? solanaChainId : chainId
  const activeAccount = activeChain === ChainId.SOLANA ? solanaAccount : account
  return { chainId: activeChain, account: activeAccount, ...web3React }
}

OnClick handler that would send a network change request to either MetaMask or Phantom Wallet when user selects one of the chains.

const handleSelection = (network: ChainId) => {
    onDismiss()
    onNetworkSelect(network)
  }

What I would like to accomplish is that if the user selected in the app ChainId.SOLANA I would like to update activeChain variable in the useActiveWeb3React hook so that the whole app also knows user now wants to be on Solana. And then if the user switches back to Ethereum I want to update the activeChain to reflect the users last selection. Also I would like to stay at that chain if user refreshes the app.

I have access to redux store in the app.

How would you do it?

Thanks for suggestions!

Julien Kode
  • 5,010
  • 21
  • 36
Digital Dom
  • 412
  • 5
  • 12

1 Answers1

2

You need three different things.

  • Save a value inside the state
  • Get a value inside the state
  • Persit the state (so when user refresh the page you still have this information)

How to save a value in the redux store ?

To avoid boilerplate redux team recommend to use redux-toolkit as the standard approach.

You can create a part of the state of your app with createSlice This will help you to create actions creator and reducers

userWallet.slice.ts

import { createSlice } from '@reduxjs/toolkit'
import type { PayloadAction } from '@reduxjs/toolkit'

interface UserWalletState {
  chainId: ChainId | null
}

const initialState = { chainId: null }

const userWalletSlice = createSlice({
  name: 'userWallet',
  initialState,
  reducers: {
    setChainId(state, action: PayloadAction<ChainId>) {
      state.chainId = action.payload
    },
  },
})

export const { setChainId } = userWalletSlice.actions
export default userWalletSlice.reducer

We create a slice named: userWalletSlice and we export the generated reducer, don't forget to add it as your reducers now:

rootReducer.ts

import userWalletReducer from './userWallet.slice.ts'

export const rootReducer = combineReducers({ userWallet: userWalletReducer })

When create this reducer inside userWallet.slice.ts:

    setChainId(state, action: PayloadAction<ChainId>) {
      state.chainId = action.payload
    },

Every time we dispatch the action setChainId. This will take the payload and update state.chainId.

When we create setChainId reducer this will automatically create an action creator that you can export.

export const { setChainId } = userWalletSlice.actions

You'll be able to dispatch it like this:

dispatch(setChainId(chainId))

Then inside your callback you can just do:

const handleSelection = (network: ChainId) => {
    onDismiss();
    dispatch(setChainId(network));
}

Now that you can put this chainId into your state, you need to retrieve automatically when it change.

How to get a value from redux store ?

To get values inside the store we use selectors.

You can use createSelector to create a memoized selector.

userWallet.selector.ts

export const userWalletSelector = (state: AppState) => state.userWallet;

export const chainIdSelector = createSelector(userWalletSelector, userWallet => userWallet.chainId)

So now inside your custom hook you can get this value with the following line.

const activeChain = useSelector(chainIdSelector);

How to persist redux state to retrieve it when I refresh a page ?

There are multiple way to persist state of you app. For your kind of information like chainId you can use tool like redux-persist to save part of your state inside the local storage for example

Julien Kode
  • 5,010
  • 21
  • 36
  • Great Answer Julien! Thanks for the time answering it. Would you also have an idea if this is doable without Redux? Or rather I should stick to redux in such a case since I am going to update the store at least from 3 different handlers? – Digital Dom Jul 21 '22 at 17:31