cult-of-coders / grapher-react

Provides easy to use React Components that are suitable for grapher package.
https://atmospherejs.com/cultofcoders/grapher-react
38 stars 19 forks source link

Provide a hook for react stateful function #41

Closed erixtekila closed 3 years ago

erixtekila commented 5 years ago

It would be interesting to have a useQuery hook.

erixtekila commented 3 years ago

Here is an implementation for those who are interested.

import { useState } from "react";
import { useTracker } from 'meteor/react-meteor-data';

/**
 * Provide a hook to get grapher's reactive query values
 * 
 * @param {Object} query A Grapher query clone
 * @param {Boolean} single Result is an object
 * @returns {Object} data Query values
 */
export default useReactiveQuery = ( query, single=false ) =>
{
    const [ data, setData ] = useState();
    const [ isLoading, setLoading ] = useState( true );
    const [ error, setError ] = useState();

    useTracker
    (
        () =>
        {
            query.subscribe
            (
                {
                    onStop( err ) 
                    {
                        if (err)
                        {
                            setError( err );
                        }
                    },
                    onReady()
                    {
                        setLoading( false );
                    }
                }
            );

            const data 
                = single
                ? query.fetchOne()
                : query.fetch();

            setData(data);
        }, []
    )

    return {
        data
        , isLoading
        , error
    }
};
import { useState, useEffect } from "react";

/**
 * Provide a hook to get grapher's non reactive query values
 * 
 * @param {Object} query A Grapher query clone
 * @param {Boolean} single Result is an object
 * @param {Number} pollingMs Polling interval or undefined if loaded once
 * @returns {Object} data Query values
 */
export default useStaticQuery = ( query, single=false, pollingMs ) =>
{
    const [ data, setData ] = useState();
    const [ isLoading, setLoading ] = useState( true );
    const [ error, setError ] = useState();

    useEffect
    (
        () =>
        {
            if( pollingMs )
            {
                const pollingInterval 
                    = setInterval
                    (
                        () =>  setLoading( true )
                        , pollingMs
                    );
                return () => clearInterval( pollingInterval );
            }
        },[]
    );

    const fetch = ( error, result ) =>
    {
        if( error ) setError( error );
        setData( result );
        setLoading( false );
    };

    useEffect
    (
        () =>
        {
            single
            ? query.fetchOne( fetch )
            : query.fetch( fetch );

        }, pollingMs ? [ isLoading ] : []
    )

    return {
        data
        , isLoading
        , error
    }
}

@theodorDiaconu you can close this issue.