@dynamic-labs-sdk/react-hooks is a thin React layer over @dynamic-labs-sdk/client. Every hook wraps a client function or a piece of client state and re-renders your component when the underlying value changes, so you rarely need to wire up useState/useEffect yourself.
This page explains the model: how hooks are named, which functions get one, and the three shapes a hook can take. For the setup steps (DynamicProvider) and a catalog of the headline state hooks, see the React Hooks reference.
Before this: create and initialize a Dynamic client (see Creating a Dynamic
Client, Initializing the
Dynamic Client) and
wrap your tree in
DynamicProvider.The naming rule
Each hook has the same name as the client function it wraps, prefixed withuse. The rest of the name is unchanged, so once you know the function you know the hook:
Client function (@dynamic-labs-sdk/client) | Hook (@dynamic-labs-sdk/react-hooks) |
|---|---|
signMessage | useSignMessage |
getFlow | useGetFlow |
getMultichainTokenBalances | useGetMultichainTokenBalances |
logout | useLogout |
updateUser | useUpdateUser |
useUser, useGetWalletAccounts, and useInitStatus.
Which functions get a hook
Not every function in the client needs a React wrapper. The rules:- Every async function gets a hook. Anything you would
await— reads likegetFlow, writes likesignMessage— has a matching hook so you get loading and error state for free. - Reactive client state is exposed as a state hook. Values that the client keeps in memory and updates over time — the current user, wallet accounts, registered wallet providers, init status, session expiry — each have a hook that re-renders on change.
- A sync function gets a hook only when its return value can change reactively. Most synchronous getters are pure and don’t need a hook — just call them. But some read live client state that changes after events (for example the linked social accounts derived from the current user, or the available wallet providers). Those get a hook so your component re-renders when the value changes; calling the bare function would give you a stale snapshot. Examples:
useGetUserSocialAccountsanduseGetAvailableWalletProvidersData. - Events are subscribed to with
useOnEvent. Any client event can be observed for a component’s lifetime — seeuseOnEvent. - Purely synchronous, non-reactive functions do not get a hook. Call them directly inside your component or an event handler.
isHardwareWalletAccount is a pure check on a wallet account object — it doesn’t change for a given input and has no hook. The reactivity comes from useGetWalletAccounts, which re-renders on connect/disconnect. useMemo avoids recomputing the filter on unrelated renders. This pattern works for any sync client function: pair a state hook for the reactive dependency with useMemo to derive the value you need.
The three shapes of a hook
A hook’s shape follows the function it wraps. All three shapes return TanStack Query result objects ({ data, isLoading, error, refetch, … }), so the loading, error, and refetch ergonomics are the standard ones you may already know.
Query hooks (async reads)
Wrap async read functions likegetNativeBalance or getMultichainTokenBalances. They fetch on mount and return the full query result — data, isLoading, isFetching, error, refetch, and so on.
Read hooks take their arguments as pseudo-required: the parameter is typed to accept undefined, and the hook stays disabled (no fetch) until you pass a real value. This lets you call the hook unconditionally — as the Rules of Hooks require — while waiting for an upstream value like a wallet account to load.
Mutation hooks (async actions)
Wrap async write functions likesignMessage, logout, or updateUser. They don’t run on mount — you trigger them by calling mutate (or mutateAsync) with the function’s arguments. They return mutate, mutateAsync, isPending, data, error, and reset.
onSuccess / onError through mutateParams to react to the result:
useDeleteMfaDevice refetches useGetMfaDevices, and useRevokeRegisteredDevice refetches useGetRegisteredDevices. You don’t need to call refetch yourself — the data stays in sync.
State hooks (reactive values)
Wrap reactive client state. They take no fetch arguments and return the same TanStack Query result as query hooks —data, isLoading, error, refetch, and so on. The hook subscribes to the relevant client events and re-renders your component whenever the value changes.
Hooks vs. calling the function directly
Both the hooks package and the client are public API. Reach for a hook when a component should react to the value or you want loading/error state managed for you. Call the client function directly for one-shot work where you don’t need re-renders — for example reading the current value inside an event handler.getDefaultClient() — no need to pass it explicitly. For the same value as reactive state that re-renders the component, use useGetWalletAccounts instead.
Related
- React Hooks reference — setup, the headline state hooks, and
useOnEvent - React Quickstart (JS SDK)
- Create a Dynamic Client
- Events Catalog