FirstEffect.purs 1.67 KB
Newer Older
1 2 3
module Gargantext.Hooks.FirstEffect
  ( useFirstMount
  , useFirstEffect, useFirstEffect'
arturo's avatar
arturo committed
4
  , useFirstLayoutEffect, useFirstLayoutEffect'
5 6 7 8 9 10 11 12
  ) where

import Gargantext.Prelude

import Effect (Effect)
import Reactix (nothing, thenNothing)
import Reactix as R

arturo's avatar
arturo committed
13 14 15 16
-- /!\ For some reasons, cleanup function works perfectly on some cases,
--     sometimes not... (@TODO? is this a React odd behavior?)
--      ↳ use `R.useFirstEffect1 []` instead of `useFirstEffect` for now

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
-- | Hook triggered on first mount event only
useFirstMount :: R.Hooks (Boolean)
useFirstMount = do
  firstMount <- R.useRef true

  let firstMount' = R.readRef firstMount

  R.unsafeHooksEffect
    if firstMount' == true
    then R.setRef firstMount false
    else nothing

  pure firstMount'

-- | Hook triggered on first mount only
useFirstEffect :: Effect (Effect Unit) -> R.Hooks Unit
useFirstEffect e = useFirstMount >>= eff e

-- | Like `useFirstEffect` but Effect fn does return a cleanup handler
useFirstEffect' :: forall a. Effect a -> R.Hooks Unit
useFirstEffect' e = useFirstMount >>= eff (e # thenNothing)

arturo's avatar
arturo committed
39 40 41 42 43 44 45 46
-- | Hook triggered on first mount only (layout hook mode)
useFirstLayoutEffect :: Effect (Effect Unit) -> R.Hooks Unit
useFirstLayoutEffect e = useFirstMount >>= eff' e

-- | Like `useFirstLayoutEffect` but Effect fn does return a cleanup handler
useFirstLayoutEffect' :: forall a. Effect a -> R.Hooks Unit
useFirstLayoutEffect' e = useFirstMount >>= eff' (e # thenNothing)

47 48
eff :: Effect (Effect Unit) -> Boolean -> R.Hooks Unit
eff e b = R.useEffect if b then e else nothing # thenNothing
arturo's avatar
arturo committed
49 50 51

eff' :: Effect (Effect Unit) -> Boolean -> R.Hooks Unit
eff' e b = R.useLayoutEffect if b then e else nothing # thenNothing