React

@solana/react veröffentlicht einen Kit-Client über einen einzigen Provider im Komponentenbaum. Hooks lesen RPC-Daten, Subscriptions und den Wallet-Status daraus. Die Browser-Wallet-Hooks befinden sich in @solana/kit-plugin-wallet/react und lesen denselben Provider – ein separater Wallet-Provider ist nicht erforderlich.

Installation

Terminal
$
npm install @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-wallet @solana/react

Client erstellen

Erstellen Sie den Client einmalig auf Modulebene, außerhalb des React-Baums. Im Browser macht walletSigner die verbundene Wallet sowohl zum Fee-Zahler als auch zur Identität.

client.ts
import { createClient } from "@solana/kit";
import { solanaRpc } from "@solana/kit-plugin-rpc";
import { walletSigner } from "@solana/kit-plugin-wallet";
export const client = createClient()
.use(walletSigner({ chain: "solana:devnet" }))
.use(solanaRpc({ rpcUrl: "https://api.devnet.solana.com" }));
export type AppClient = Awaited<typeof client>;

walletSigner fügt client.wallet hinzu (Wallet Standard-Erkennung und -Verbindung), und solanaRpc fügt client.rpc sowie den Hilfs-Helper client.sendTransaction hinzu. Exportieren Sie den Client-Typ in Awaited<> eingebettet, damit er korrekt bleibt, wenn Sie später ein Plugin hinzufügen, das asynchron auflöst, und übergeben Sie diesen AppClient an jeden useClient-Aufruf.

Den Baum einmalig umschließen

ClientProvider veröffentlicht den Client. Die Daten-Hooks (useRequest, useSubscription, useTrackedData) lesen ihn über useClient. Die unten aufgeführten Wallet-Hooks benötigen denselben Client explizit als erstes Argument.

providers.tsx
"use client";
import { ClientProvider } from "@solana/react";
import { client } from "./client";
export function Providers({ children }: { children: React.ReactNode }) {
return <ClientProvider client={client}>{children}</ClientProvider>;
}

Wallet-Hooks

Die Wallet-Hooks benötigen einen Client mit installiertem Wallet-Plugin (z. B. walletSigner). Holen Sie ihn über useClient<AppClient>() und übergeben Sie ihn als erstes Argument jedes Hooks – so bleibt die App vollständig typisiert von Anfang bis Ende, anstatt auf Context-Lookups angewiesen zu sein.

  • useWallets(client) — Über den Wallet Standard erkannte Wallets für die Chain des Clients.
  • useWalletStatus(client)"pending" | "disconnected" | "connecting" | "connected" | "disconnecting" | "reconnecting".
  • useConnectedWallet(client){ account, signer, wallet } oder null. signer ist null bei schreibgeschützten Wallets.
  • useConnect(client) / useDisconnect(client) — geben ein ActionResult zurück, dessen dispatch (und dispatchAsync) die Aktion ausführt und dessen isRunning, status, data, error und reset das Ergebnis verfolgen.
"use client";
import {
useConnect,
useConnectedWallet,
useDisconnect,
useWallets,
useWalletStatus
} from "@solana/kit-plugin-wallet/react";
import { useClient } from "@solana/react";
import type { AppClient } from "./client";
function WalletPanel() {
const client = useClient<AppClient>();
const status = useWalletStatus(client);
const wallets = useWallets(client);
const connected = useConnectedWallet(client);
const connect = useConnect(client);
const disconnect = useDisconnect(client);
if (status === "pending") return null; // wait out auto-reconnect
if (connected) {
return (
<div>
<p>{connected.account.address}</p>
<button onClick={() => disconnect.dispatch()}>Disconnect</button>
</div>
);
}
return (
<div>
{wallets.map((wallet) => (
<button
key={wallet.name}
disabled={connect.isRunning}
onClick={() => connect.dispatch(wallet)}
>
Connect {wallet.name}
</button>
))}
</div>
);
}

Eine Transaktion senden

useClient gibt denselben Client zurück, den Sie veröffentlicht haben. Erstellen Sie Anweisungen mit einem generierten Programm-Client und senden Sie sie über client.sendTransaction.

"use client";
import { address, lamports } from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
import { useClient } from "@solana/react";
import { useConnectedWallet } from "@solana/kit-plugin-wallet/react";
import type { AppClient } from "./client";
function SendSol({ destination }: { destination: string }) {
const client = useClient<AppClient>();
const connected = useConnectedWallet(client);
async function handleSend() {
if (!connected?.signer) return;
const transfer = getTransferSolInstruction({
source: connected.signer,
destination: address(destination),
amount: lamports(10_000_000n) // 0.01 SOL
});
const result = await client.sendTransaction([transfer]);
console.log("sent", result.context.signature);
}
return (
<button disabled={!connected?.signer} onClick={handleSend}>
Send 0.01 SOL
</button>
);
}

Durch Übergabe des exportierten AppClient-Typs an useClient erhält der Hook den vollständig plugin-erweiterten Client, sodass client.rpc und client.sendTransaction typisiert sind.

Daten lesen

@solana/react stellt Hooks bereit, die Daten über den Client lesen:

  • useRequest(source) — Einmaliger RPC-Lesevorgang; gibt { data, error, status, refresh } zurück.
  • useSubscription(source) — Eine Live-Subscription; gibt { data, error, reconnect, status } zurück.
  • useTrackedData(spec) — Ein per RPC initialisierter Wert, der durch eine Subscription aktuell gehalten wird.
"use client";
import { address } from "@solana/kit";
import { useClient, useRequest } from "@solana/react";
import { useMemo } from "react";
import type { AppClient } from "./client";
function Balance({ owner }: { owner: string }) {
const client = useClient<AppClient>();
const source = useMemo(
() => client.rpc.getBalance(address(owner)),
[client, owner]
);
const { data, status, refresh } = useRequest(source);
if (status === "fetching") return <p>Loading…</p>;
if (status === "error") return <p role="alert">RPC error</p>;
return (
<div>
<p>Lamports: {data?.value.toString()}</p>
<button onClick={() => refresh()}>Refresh</button>
</div>
);
}

Memoisieren Sie die Quelle (mit useMemo oder useCallback für eine Funktion), damit der Hook nur bei Änderung seiner Eingaben neu abruft und nicht bei jedem Render.

Für Caching und Revalidierung umschließen die Subpfade @solana/react/swr und @solana/react/query dieselben Hooks für SWR und TanStack Query.

Gängige Muster für Solana-Entwickler

  • Ein Provider: ClientProvider ist der einzige Provider, den Sie benötigen; holen Sie den Client mit useClient<AppClient>() und übergeben Sie ihn an die Wallet-Hooks.
  • Server-Komponenten-kompatibel: Markieren Sie nur Blatt-Komponenten, die Hooks aufrufen, mit "use client"; Server-Lesevorgänge können einen einfachen Kit-RPC-Client ohne Wallet verwenden.
  • Testing: Veröffentlichen Sie einen gemockten Client über ClientProvider, um Wallets und RPC-Antworten zu simulieren.

Zwei Hook-Familien, gleiche Namen

useSignIn und useSignMessage existieren sowohl in @solana/react (sie nehmen ein UiWalletAccount-Argument) als auch in @solana/kit-plugin-wallet/react (nehmen stattdessen den client und geben ein ActionResult zurück). Verwenden Sie die Versionen aus @solana/kit-plugin-wallet/react mit dem oben beschriebenen Client-Muster; die älteren @solana/react-Wallet-Hooks werden abgelöst.

Ergänzen Sie diesen Leitfaden mit der Kit-Client-Übersicht, um zu verstehen, welchen Client jeder Hook liest.

Is this page helpful?

Inhaltsverzeichnis

Seite bearbeiten
© 2026 Solana Foundation. Alle Rechte vorbehalten.