UNPKG

@buddy-link/react

Version:

Buddy SDK - React components and hooks for wallet integration

58 lines (48 loc) 2.09 kB
"use client"; import { useEffect, useState, useMemo } from "react"; import { uuid } from "./_uuid"; import { getStateInstance } from "./_init"; /** * Custom hook to subscribe and interact with a global state using a unique key and an optional selector function. * @param {string} key The key to identify the particular state to subscribe to. * @param {Function} [selector] An optional function to transform or select a part of the state. * @returns An array containing the selected state value and a function to update the source state. */ export const useBuddyState = (key, selector) => { const uniqueId = uuid(); // Generates a unique ID for the subscription. const stateInstance = getStateInstance(); // Retrieves the global state instance. const source = stateInstance.getSource(key); // Retrieves the source observable based on the key. // State to hold the value from the observable source. const [value, setValue] = useState(source?.getValue()); // Observer object to interact with the observable source. const observer = useMemo(() => ({ id: uniqueId, /** * @param {any} nextValue */ next(nextValue) { setValue(nextValue); // Updates state value when observable pushes new values. }, complete() { setValue(undefined); // Resets state value when observable is completed. }, }), [uniqueId]); // useEffect hook to subscribe to the source on mount and unsubscribe on unmount. useEffect(() => { source?.subscribe(observer); return () => source?.unsubscribe(observer.id); }, [source, observer]); // Function to update the observable source's value. const updateSource = (/** @type {(arg0: any) => any} */ nextValue) => { if (typeof nextValue === 'function') { source?.next(nextValue(source.getValue())) } else { source?.next(nextValue) } }; // useMemo hook to apply the selector function to the state value if provided. const selectedValue = useMemo(() => selector ? selector(value) : value, [value, selector] ); return [selectedValue, updateSource]; };