Skip to content
IC Reactor

Custom Provider

This example demonstrates how to build a Token Viewer where the user can input any Canister ID, and the app dynamically connects to it. This requires creating a custom Context Provider that instantiates a Reactor based on props.

  • Dynamic Canister IDs: Connecting to canisters determined at runtime.
  • Context API: Passing the reactor instance down to children.
  • Reusability: Creating a generic ICRC1Provider that can wrap any part of the app.
src/ICRC1Provider.tsx
import { PropsWithChildren, createContext, useMemo } from "react"
import { Reactor, createActorHooks, ActorHooks } from "@ic-reactor/react"
import { idlFactory, type ICRC1 } from "./declarations/icrc1"
import { clientManager } from "./reactor"
// `ActorHooks` takes two type parameters: the service, and the transform
// the reactor was built with ("candid" here, "display" for a DisplayReactor).
type ICRC1Hooks = ActorHooks<ICRC1, "candid">
interface ICRC1ContextValue {
canisterId: string
hooks: ICRC1Hooks
}
const ICRC1Context = createContext<ICRC1ContextValue | null>(null)
interface ICRC1ProviderProps extends PropsWithChildren {
canisterId: string
}
const ICRC1Provider: React.FC<ICRC1ProviderProps> = ({
children,
canisterId,
}) => {
// Rebuild the reactor and its hooks whenever the canister ID changes
const hooks = useMemo<ICRC1Hooks>(() => {
const reactor = new Reactor<ICRC1>({
name: "icrc1",
clientManager,
canisterId,
idlFactory,
})
return createActorHooks(reactor)
}, [canisterId])
return (
<ICRC1Context.Provider value={{ canisterId, hooks }}>
{children}
</ICRC1Context.Provider>
)
}
export default ICRC1Provider