@solana/react mempublikasikan Kit client ke pohon komponen Anda melalui satu
provider, lalu hooks membaca data RPC, langganan, dan status wallet darinya. Hooks
wallet browser berada di @solana/kit-plugin-wallet/react dan membaca provider
yang sama — tidak ada wallet provider terpisah.
Instalasi
$npm install @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-wallet @solana/react
Bangun client
Bangun client sekali, di lingkup modul, di luar pohon React. Di browser,
walletSigner menjadikan wallet yang terhubung sebagai pembayar biaya sekaligus identitas.
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 menambahkan client.wallet (penemuan dan koneksi Wallet Standard),
dan solanaRpc menambahkan client.rpc beserta helper client.sendTransaction.
Ekspor tipe client yang dibungkus dalam Awaited<> agar tetap benar jika Anda
kemudian menambahkan plugin yang diselesaikan secara asinkron, dan berikan AppClient
tersebut ke setiap pemanggilan useClient.
Bungkus pohon Anda sekali
ClientProvider mempublikasikan client. Hooks data (useRequest,
useSubscription, useTrackedData) membacanya melalui useClient. Hooks wallet
di bawah ini membutuhkan client yang sama yang diteruskan secara eksplisit sebagai argumen pertama mereka.
"use client";import { ClientProvider } from "@solana/react";import { client } from "./client";export function Providers({ children }: { children: React.ReactNode }) {return <ClientProvider client={client}>{children}</ClientProvider>;}
Hooks wallet
Hooks wallet membutuhkan client dengan plugin wallet yang terpasang (misalnya
walletSigner). Dapatkan dari useClient<AppClient>() dan teruskan sebagai
argumen pertama setiap hook — ini menjaga agar aplikasi tetap sepenuhnya bertipe
dari ujung ke ujung, alih-alih mengandalkan pencarian konteks.
useWallets(client)— Wallet Standard yang ditemukan untuk chain client.useWalletStatus(client)—"pending" | "disconnected" | "connecting" | "connected" | "disconnecting" | "reconnecting".useConnectedWallet(client)—{ account, signer, wallet }ataunull.signerbernilainulluntuk wallet hanya-baca.useConnect(client)/useDisconnect(client)— mengembalikanActionResultyangdispatch-nya (dandispatchAsync) menjalankan aksi, sertaisRunning,status,data,error, danreset-nya melacak hasilnya.
"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-reconnectif (connected) {return (<div><p>{connected.account.address}</p><button onClick={() => disconnect.dispatch()}>Disconnect</button></div>);}return (<div>{wallets.map((wallet) => (<buttonkey={wallet.name}disabled={connect.isRunning}onClick={() => connect.dispatch(wallet)}>Connect {wallet.name}</button>))}</div>);}
Kirim transaksi
useClient mengembalikan client yang sama yang Anda publikasikan. Bangun instruksi
dengan program client yang dihasilkan dan kirimkan melalui 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>);}
Meneruskan tipe AppClient yang diekspor ke useClient memberikan hook client
yang diperluas penuh oleh plugin sehingga client.rpc dan client.sendTransaction
memiliki tipe yang benar.
Baca data
@solana/react menyediakan hooks yang membaca melalui client:
useRequest(source)— pembacaan RPC sekali jalan; mengembalikan{ data, error, status, refresh }.useSubscription(source)— langganan langsung; mengembalikan{ data, error, reconnect, status }.useTrackedData(spec)— nilai yang diisi dari RPC dan diperbarui secara langsung melalui langganan.
"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>);}
Memoize sumber (dengan useMemo, atau useCallback untuk fungsi) agar hook
hanya mengambil ulang data ketika inputnya berubah, bukan setiap kali render.
Untuk caching dan revalidasi, subpath @solana/react/swr dan @solana/react/query
membungkus hooks yang sama untuk SWR dan
TanStack Query.
Pola umum untuk pengembang Solana
- Satu provider:
ClientProvideradalah satu-satunya provider yang Anda butuhkan; dapatkan client denganuseClient<AppClient>()dan teruskan ke hooks wallet. - Mendukung server components: Tandai hanya komponen daun yang memanggil hooks
dengan
"use client"; pembacaan di sisi server dapat menggunakan Kit RPC client biasa tanpa wallet. - Pengujian: Publikasikan client yang di-mock melalui
ClientProvideruntuk mensimulasikan wallet dan respons RPC.
Dua keluarga hook, nama yang sama
useSignIn dan useSignMessage ada di @solana/react (menggunakan argumen
UiWalletAccount) maupun di @solana/kit-plugin-wallet/react (menggunakan
client, mengembalikan ActionResult). Gunakan versi
@solana/kit-plugin-wallet/react dengan pola client di atas; hooks wallet
@solana/react yang lebih lama sedang digantikan.
Padukan panduan ini dengan gambaran umum Kit client untuk memahami client yang dibaca oleh setiap hook.
Is this page helpful?