# createReactorProvider

> **createReactorProvider**\<`TValue`, `TProps`\>(`factory`, `options?`): [`CreateReactorProviderReturn`](https://ic-reactor.b3pay.net/v3/libs/interfaces/createreactorproviderreturn/)\<`TValue`, `NonNullable`\<`TProps`\>\>

Defined in: [react/src/createReactorProvider.ts:196](https://github.com/B3Pay/ic-reactor/blob/f1956947ae037304fce1675a38695964c1aa9e32/packages/react/src/createReactorProvider.ts#L196)

Creates a provider that builds an app's reactors once per mounted tree, and
a `useReactor()` hook that returns what it built, fully typed.

This is the setup a server-rendered app needs. The factory runs in a
`useState` initializer, once per mounted tree, and a server render is a tree
of its own: each request builds its own `ClientManager`, `QueryClient`,
reactors and `AuthenticationManager`, so no cache or identity is shared
between visitors. The first render needs no effect, so the server's HTML is
complete, and the browser builds a fresh value from the same props to
hydrate it. In a client-only app it works the same, one value per mount.

The factory returns anything: a `defineReactor` or `defineDisplayReactor`
result, a record of them, reactors and managers built by hand, query and
mutation objects from `createQuery` or `createMutation`. `useReactor()`
returns it with the factory's own return type, so its hooks keep their
generic signatures. `useReactor("todo")` returns one property of it.

When the tree unmounts, the provider disposes each `AuthenticationManager`
built for the value, releasing the Internet Identity client it built: those
constructed while the factory ran, and the one a `defineReactor` result in
the value, or among its own properties, builds on first use (a result that
never used authentication builds none). A manager built elsewhere and
handed in, such as an app-wide one passed as `authentication` or as a
prop, is left to whoever built it. `dispose()` only forgets the client, and
the next sign-in builds a new one, so this is safe under StrictMode, which
runs the cleanup and then the effect again on the same value.

It also renders a `QueryClientProvider` for the value's QueryClient; see
[CreateReactorProviderOptions.queryClientProvider](https://ic-reactor.b3pay.net/v3/libs/interfaces/createreactorprovideroptions/#queryclientprovider).

A suspense hook below the provider may suspend its first render: React
renders the same element again when the data arrives, and the provider
reuses the value that first render built, whether the Suspense boundary
sits above the provider or, while hydrating, there is none. A provider that
a transition mounts (`startTransition`, a client-side navigation) can be
rendered from a new element on each retry and build a new value each time,
so give its suspending components a `<Suspense>` boundary inside it.

Call `createReactorProvider` at module scope: it builds nothing itself,
only the context, and every mounted provider builds its own value. In the
Next.js App Router that module needs `"use client"`, like any module with
hooks; a server component renders the provider from there.

## Type Parameters

### TValue

`TValue` *extends* `object`

### TProps

`TProps` *extends* `object` \| `undefined` = \{ \}

## Parameters

### factory

(`props`) => `TValue`

Builds the value. It receives the provider's props other
than `children`, and runs once per mounted provider.

### options?

[`CreateReactorProviderOptions`](https://ic-reactor.b3pay.net/v3/libs/interfaces/createreactorprovideroptions/) = `{}`

See [CreateReactorProviderOptions](https://ic-reactor.b3pay.net/v3/libs/interfaces/createreactorprovideroptions/).

## Returns

[`CreateReactorProviderReturn`](https://ic-reactor.b3pay.net/v3/libs/interfaces/createreactorproviderreturn/)\<`TValue`, `NonNullable`\<`TProps`\>\>

## Examples

**One canister, with Internet Identity**

```tsx
"use client"
import { createReactorProvider, defineReactor } from "@ic-reactor/react"
import { canisterId, idlFactory, type _SERVICE } from "./declarations/todo"

export const { ReactorProvider, useReactor } = createReactorProvider(() =>
  defineReactor<_SERVICE>({ name: "todo", idlFactory, canisterId })
)

function Todos() {
  const { useActorQuery, useAuth } = useReactor()
  const { isAuthenticated } = useAuth()
  const { data } = useActorQuery({ functionName: "getAllTodos" })
  return <p>{isAuthenticated ? data?.length : "Sign in"}</p>
}

// app/layout.tsx (a server component)
// <ReactorProvider>{children}</ReactorProvider>
```

**Several canisters sharing one agent and one sign-in**

```tsx
export const { ReactorProvider, useReactor } = createReactorProvider(() => {
  const backend = defineReactor<Backend>({
    name: "backend",
    idlFactory: backendIdl,
    canisterId: backendId,
  })
  const ledger = defineDisplayReactor<Ledger>({
    name: "ledger",
    idlFactory: ledgerIdl,
    canisterId: ledgerId,
    authentication: backend.authentication,
  })
  return { backend, ledger }
})

function Balance() {
  const { data } = useReactor("ledger").useActorQuery({
    functionName: "icrc1_total_supply",
  })
  return <span>{data}</span>
}
```

**Props for the factory, and a new key to build again**

```tsx
export const { ReactorProvider: LedgerProvider, useReactor: useLedger } =
  createReactorProvider(({ canisterId }: { canisterId: string }) =>
    defineDisplayReactor<Ledger>({ name: "ledger", idlFactory, canisterId })
  )

// Read once per mount: the key makes a new canister a new tree.
<LedgerProvider key={canisterId} canisterId={canisterId}>
  <TokenPage />
</LedgerProvider>
```