@macalinao/grill
Version:
Modern Solana development kit for React applications with automatic account batching, caching, and transaction notifications
68 lines • 2.67 kB
JavaScript
import { useEffect, useRef } from "react";
import { useSubscriptionManager } from "../contexts/subscription-context.js";
/**
* Hook to subscribe to account changes via the SubscriptionManager.
*
* This hook:
* - Uses the SubscriptionManager for de-duplicated WebSocket subscriptions
* - Only creates one subscription per account address across all components
* - Automatically cleans up when all subscribers unmount
* - Updates React Query cache when account data changes
*
* @param address - The account address to subscribe to, or null/undefined to skip
* @param decoder - Function to decode the account data (must be stable reference)
* @param enabled - Whether the subscription should be active
*
* @example
* ```tsx
* function MyComponent() {
* const minerPda = useMinerPda({ authority });
*
* // Subscribe to account changes
* useAccountSubscription(minerPda, decodeMiner, true);
*
* // Use the standard account hook for data - it gets updated by the subscription
* const { data: miner } = useAccount({ address: minerPda, decoder: decodeMiner });
*
* return <div>{miner?.data.authority}</div>;
* }
* ```
*/
export function useAccountSubscription(address, decoder, enabled) {
const manager = useSubscriptionManager();
// Use ref to track the current unsubscribe function
const unsubscribeRef = useRef(null);
// Track the current address to detect changes
const currentAddressRef = useRef(null);
useEffect(() => {
// Skip if not enabled, no address, or no decoder
if (!(enabled && address && decoder)) {
// Clean up any existing subscription
if (unsubscribeRef.current) {
unsubscribeRef.current();
unsubscribeRef.current = null;
currentAddressRef.current = null;
}
return;
}
// If address changed, clean up old subscription first
if (currentAddressRef.current !== address) {
if (unsubscribeRef.current) {
unsubscribeRef.current();
unsubscribeRef.current = null;
}
}
// Subscribe to the new address
currentAddressRef.current = address;
unsubscribeRef.current = manager.subscribe(address, decoder);
// Cleanup on unmount or when dependencies change
return () => {
if (unsubscribeRef.current) {
unsubscribeRef.current();
unsubscribeRef.current = null;
currentAddressRef.current = null;
}
};
}, [manager, address, decoder, enabled]);
}
//# sourceMappingURL=use-account-subscription.js.map