import { Semigroup } from 'fp-ts/lib/Semigroup' ; import * as O from 'fp-ts/lib/Option' ; import * as QR from '../QueryResult' ; import { product , ObservableQuery } from '../Query' ; import { EnforceNonEmptyRecord , ObservableQueries , ProductL , ProductP , ProductA , VoidInputObservableQueries } from '../util' ; import { keepQueryResultSemigroup } from './Semigroup' ; import { observable } from '../Observable' ; import { observeShallow } from '../observe' ; import { eqShallow } from '../Strategy' ; import { useRef , useEffect , useState , useMemo } from 'react' ; import { pipe } from 'fp-ts/lib/pipeable' ; import { constFalse } from 'fp-ts/lib/function' ; function usePrevious < T > ( value ) { const ref = useRef < T > ( ) ; useEffect ( ( ) => { ref . current = value ; } ) ; return O . fromNullable ( ref . current ) ; } param query param params param resultSemigroup returns example export function useQuery < L , P > ( query , params ? , resultSemigroup ? ) ; export function useQuery < A , L , P > ( query , params , resultSemigroup ? ) ; export function useQuery < A , L , P > ( query , params , resultSemigroup ? ) { const _resultSemigroup = resultSemigroup || keepQueryResultSemigroup < L , P > ( ) ; const [ state , setState ] = useState < QR . QueryResult < L , P > > ( QR . queryResultLoading ) ; const previousInput = usePrevious ( params ) ; const [ inputEquality , setInputEquality ] = useState ( 0 ) ; useEffect ( ( ) => { const inputChanged = pipe ( previousInput , O . fold ( constFalse , previousInput => ! query . inputEq . equals ( previousInput , params ) ) ) ; if ( inputChanged ) { setInputEquality ( inputEquality + 1 ) ; } } ) ; const lastState = useRef ( state ) ; useEffect ( ( ) => { lastState . current = state ; } , [ state ] ) ; const lastParams = useMemo ( ( ) => params , [ inputEquality ] ) ; useEffect ( ( ) => { const subscription = observable . map ( observeShallow ( query , lastParams ) , r => _resultSemigroup . concat ( lastState . current , r ) ) . subscribe ( setState ) ; return ( ) => { subscription . unsubscribe ( ) ; } ; } , [ query , lastParams ] ) ; return state ; } param queries param params param resultSemigroup returns example export function useQueries < R extends VoidInputObservableQueries > ( queries , input ? , resultSemigroup ? ) ; export function useQueries < R extends ObservableQueries > ( queries , input , resultSemigroup ? ) ; export function useQueries < R extends ObservableQueries > ( queries , params ? , resultSemigroup ? ) { const previousQueries = usePrevious ( queries ) ; const [ queriesEquality , setQueriesEquality ] = useState ( 0 ) ; const queryProduct = useMemo ( ( ) => product ( queries ) , [ queriesEquality ] ) ; useEffect ( ( ) => { const queriesChanged = pipe ( previousQueries , O . fold ( constFalse , previousQueries => ! eqShallow . equals ( previousQueries , queries ) ) ) ; if ( queriesChanged ) { setQueriesEquality ( queriesEquality + 1 ) ; } } ) ; return useQuery ( queryProduct , ( params || { } ) as any , resultSemigroup ) ; } export default useQueries ;