🔑 关键词:
wallet state、Zustand、连接状态共享、自动连接、地址变更监听、网络切换处理、跨模块通信
前端连接钱包后,需要持续维护以下状态:
如果项目较大,UI 组件跨页面或模块,频繁重复使用 useAccount()、useNetwork() 等 Hook 会引起:
因此,建议使用全局状态管理库(如 Zustand)统一管理钱包状态。
// 方式一: create
import { create } from 'zustand'
export const useWalletStore = create()((set) => ({
address: null,
isConnected: false,
chainId: null,
connector: null,
isContractWallet: false,
ensName: null,
setWalletInfo: (info) => set(info),
resetWallet: () =>
set({
address: null,
isConnected: false,
chainId: null,
connector: null,
isContractWallet: false,
ensName: null,
}),
}))
// 使用方式: 获取值:最小化订阅;修改值:setState({})
// create() 返回的 Hook 必须通过 selector 函数访问 state
const address = useWalletStore(s=> s.address) // // 好:只订阅需要的字段,避免不必要的重渲染
console.log('账户地址:', address);
// ❌ 不推荐(会订阅所有字段),会导致组件在任何状态字段变更时都重新渲染,不利于性能优化
// const state = useStore()
// 方式二: createStore
import { createStore] from 'zustand/vanilla'
export const walletStore = createStore()((set) => ({
address: null,
isConnected: false,
chainId: null,
connector: null,
isContractWallet: false,
ensName: null,
setWalletInfo: (info) => set(info),
resetWallet: () =>
set({
address: null,
isConnected: false,
chainId: null,
connector: null,
isContractWallet: false,
ensName: null,
}),
}))
// 使用方式:getState() 获取值;setState({}) 设置值
const {address,chainId} = walletStore.getState();
walletStore.setState({address: '0x2343444.....', chainId: '1'})
Zustand 本体是一个极简状态容器,并不内置持久化能力。但它提供了官方中间件插件 zustand/middleware (详情见文章末尾)