React.Basic.Hooks.Internal
- Package
- purescript-react-basic-hooks
- Repository
- spicydonuts/purescript-react-basic-hooks
#Render Source
newtype Render x y a
Render represents the effects allowed within a React component's
body, i.e. during "render". This includes hooks and ends with
returning JSX (see pure
), but does not allow arbitrary side
effects.
The x
and y
type arguments represent the stack of effects that this
Render
implements, with x
being the stack at the start of this
Render
, and y
the stack at the end.
See purescript-indexed-monad to understand how the order of the stack is enforced at the type level.
Instances
IxFunctor Render
IxApply Render
IxApplicative Render
IxBind Render
Functor (Render x y)
(TypeEquals x y) => Apply (Render x y)
(TypeEquals x y) => Applicative (Render x y)
(TypeEquals x y) => Bind (Render x y)
(TypeEquals x y, Semigroup a) => Semigroup (Render x y a)
(TypeEquals x y, Monoid a) => Monoid (Render x y a)
#coerceHook Source
coerceHook :: forall a newHook oldHook hooks. Newtype newHook oldHook => Render hooks oldHook a -> Render hooks newHook a
Rename/alias a chain of hooks. Useful for exposing a single "clean" type when creating a hook to improve error messages and hide implementation details, particularly for libraries hiding internal info.
For example, the following alias is technically correct but
when inspecting types or error messages the alias is expanded
to the full original type and UseAff
is never seen:
type UseAff deps a hooks
= UseEffect deps (UseState (Result a) hooks)
useAff :: ... -> Hook (UseAff deps a) (Result a)
useAff deps aff = React.do
...
coerceHook
allows the same code to safely export a newtype
instead, hiding the internal implementation:
newtype UseAff deps a hooks
= UseAff (UseEffect deps (UseState (Result a) hooks))
derive instance ntUseAff :: Newtype (UseAff deps a hooks) _
useAff :: ... -> Hook (UseAff deps a) (Result a)
useAff deps aff = coerceHook React.do
...
#unsafeHook Source
unsafeHook :: forall a newHook. Effect a -> Hook newHook a
Promote an arbitrary Effect to a Hook.
This is unsafe because it allows arbitrary
effects to be performed during a render, which
may cause them to be run many times by React.
This function is primarily for constructing
new hooks using the FFI. If you just want to
alias a safe hook's effects, prefer coerceHook
.
It's also unsafe because the author of the hook
type (the newHook
type variable used here) MUST
contain all relevant types. For example, UseState
has a phantom type to track the type of the value contained.
useEffect
tracks the type used as the deps. useAff
tracks
both the deps and the resulting response's type. Forgetting
to do this allows the consumer to reorder hook effects. If
useState
didn't track the return type the following
extremely unsafe code would be allowed:
React.do
if xyz then
_ <- useState 0
useState Nothing
else
s <- useState Nothing
_ <- useState 0
pure s
...
The same applies to deps
in these examples as they use
Eq
and a reorder would allow React to pass incorrect
types into the eq
function!
#unsafeRenderEffect Source
unsafeRenderEffect :: forall a. Effect a -> Pure a
Promote an arbitrary Effect to a Pure render effect.
This is unsafe because it allows arbitrary
effects to be performed during a render, which
may cause them to be run many times by React.
You should almost always prefer useEffect
!