React Hook: useData()

Date: 2023-06-01
/* eslint-disable react-hooks/exhaustive-deps */
import { Dispatch, SetStateAction, useEffect, useState } from "react";

export interface IData<T> {
    data: T;
    loading: boolean;
    setData: Dispatch<SetStateAction<T>>;
    updateData: () => any;
}
export function useData<T>(fetchFn: () => PromiseLike<T>, deps: any[] = []): IData<T> {
    const [trigger, setTrigger] = useState<boolean>(false);
    const [data, setData] = useState<T>();
    const [loading, setLoading] = useState(true);
    useEffect(() => {
        async function fetch() {
            setLoading(true);
            try {
                const newData = await fetchFn();
                setData(newData);
            } finally {
                setLoading(false);
            }
        }
        fetch();
    }, [trigger, ...deps]); // do not include fetchFn here to allow inline functions as arg: useData(() => getAsync(), [])
    return {
        data,
        loading,
        setData,
        updateData: () => setTrigger(!trigger)
    } as IData<T>;
}

Example component:

export function UserInfo(props: { userId: string }): React.ReactElement {
    const ds = useData(() => appDomain.IUserService.loadUser(props.userId), [props.userId]);
    const user = ds.data;
    
    return <div>
        Loading: {ds.loading}
        User name: {user?.name}
        <button type="button" onClick={ds.updateData}>Refresh</button>
    </div>;
}
78270cookie-checkReact Hook: useData()