@@ -40,41 +40,46 @@ module React.Basic.Hooks
4040 , useMemo
4141 , UseMemoLazy
4242 , useMemoLazy
43+ , UnsafeReference (..)
4344 , Render
4445 , Pure
4546 , Hook
4647 , bind
4748 , discard
48- , pure
4949 , displayName
5050 , module React.Basic
5151 , module Data.Tuple
5252 , module Data.Tuple.Nested
5353 ) where
5454
55- import Prelude hiding (bind , discard , pure )
55+ import Prelude hiding (bind , discard )
5656
57- import Control.Applicative.Indexed (class IxApplicative , ipure )
57+ import Control.Applicative.Indexed (class IxApplicative )
5858import Control.Apply.Indexed (class IxApply )
5959import Control.Bind.Indexed (class IxBind , ibind )
6060import Data.Function.Uncurried (Fn2 , mkFn2 )
6161import Data.Functor.Indexed (class IxFunctor )
6262import Data.Maybe (Maybe )
63+ import Data.Newtype (class Newtype )
6364import Data.Nullable (Nullable , toMaybe )
6465import Data.Tuple (Tuple (..))
6566import Data.Tuple.Nested (tuple2 , (/\))
6667import Effect (Effect )
6768import Effect.Uncurried (EffectFn1 , EffectFn2 , EffectFn3 , mkEffectFn1 , runEffectFn1 , runEffectFn2 , runEffectFn3 )
68- import Prelude (bind , pure ) as Prelude
69+ import Prelude (bind ) as Prelude
6970import React.Basic (JSX , ReactComponent , empty , keyed , fragment , element , elementKeyed )
71+ import Type.Equality (class TypeEquals )
7072import Unsafe.Coerce (unsafeCoerce )
73+ import Unsafe.Reference (unsafeRefEq )
7174
72- -- | Alias for convenience. Creating components is effectful because
73- -- | React uses the function instance as the component's "identity"
74- -- | or "type".
75+ -- | Alias for convenience.
7576type CreateComponent props = Effect (ReactComponent props )
7677
7778-- | Create a React component given a display name and render function.
79+ -- | Creating components is effectful because React uses the function
80+ -- | instance as the component's "identity" or "type". Components should
81+ -- | be created during a bootstrap phase and not within component
82+ -- | lifecycles or render functions.
7883component
7984 :: forall hooks props
8085 . String
@@ -191,6 +196,11 @@ useMemoLazy
191196 -> Hook (UseMemoLazy a ) a
192197useMemoLazy key computeA = Render (runEffectFn3 useMemoLazy_ (mkFn2 eq) key computeA)
193198
199+ newtype UnsafeReference a = UnsafeReference a
200+ derive instance newtypeUnsafeReference :: Newtype (UnsafeReference a ) _
201+ instance eqUnsafeReference :: Eq (UnsafeReference a ) where
202+ eq = unsafeRefEq
203+
194204-- | Render represents the effects allowed within a React component's
195205-- | body, i.e. during "render". This includes hooks and ends with
196206-- | returning JSX (see `pure`), but does not allow arbitrary side
@@ -207,20 +217,32 @@ instance ixFunctorRender :: IxFunctor Render where
207217instance ixApplyRender :: IxApply Render where
208218 iapply (Render f) (Render a) = Render (apply f a)
209219
220+ instance ixApplicativeRender :: IxApplicative Render where
221+ ipure a = Render (pure a)
222+
210223instance ixBindRender :: IxBind Render where
211224 ibind (Render m) f = Render (Prelude .bind m \a -> case f a of Render b -> b)
212225
213- instance ixApplicativeRender :: IxApplicative Render where
214- ipure a = Render (Prelude .pure a)
215-
226+ -- | Exported for use with qualified-do syntax
216227bind :: forall a b x y z m . IxBind m => m x y a -> (a -> m y z b ) -> m x z b
217228bind = ibind
218229
230+ -- | Exported for use with qualified-do syntax
219231discard :: forall a b x y z m . IxBind m => m x y a -> (a -> m y z b ) -> m x z b
220232discard = ibind
221233
222- pure :: forall a x m . IxApplicative m => a -> m x x a
223- pure = ipure
234+ instance functorRender :: Functor (Render x y ) where
235+ map f (Render a) = Render (map f a)
236+
237+ instance applyRender :: TypeEquals x y => Apply (Render x y ) where
238+ apply (Render f) (Render a) = Render (apply f a)
239+
240+ instance applicativeRender :: TypeEquals x y => Applicative (Render x y ) where
241+ pure a = Render (pure a)
242+
243+ instance bindRender :: TypeEquals x y => Bind (Render x y ) where
244+ bind (Render m) f = Render (Prelude .bind m \a -> case f a of Render b -> b)
245+
224246
225247-- | Retrieve the Display Name from a `ReactComponent`. Useful for debugging and improving
226248-- | error messages in logs.
0 commit comments