React.Basic.Hooks
- Package
- purescript-react-basic-hooks
- Repository
- spicydonuts/purescript-react-basic-hooks
#component Source
component :: forall hooks props. String -> (props -> Render Unit hooks JSX) -> Component props
Create a component function given a display name and render function. Creating components is effectful because React uses the function instance as the component's "identity" or "type". Components should be created during a bootstrap phase and not within component lifecycles or render functions.
#reactComponent Source
reactComponent :: forall hooks props. Lacks "children" props => Lacks "key" props => Lacks "ref" props => String -> (Record props -> Render Unit hooks JSX) -> Effect (ReactComponent (Record props))
Create a React component given a display name and render function.
Creating components is effectful because React uses the function
instance as the component's "identity" or "type". Components should
be created during a bootstrap phase and not within component
lifecycles or render functions. See componentWithChildren
if
you need to use the children
prop.
#reactComponentWithChildren Source
reactComponentWithChildren :: forall hooks props children. Lacks "key" props => Lacks "ref" props => String -> ({ children :: ReactChildren children | props } -> Render Unit hooks JSX) -> Effect (ReactComponent { children :: ReactChildren children | props })
Create a React component given a display name and render function.
This is the same as component
but allows the use of the children
prop.
#reactComponentFromHook Source
reactComponentFromHook :: forall hooks props r. Lacks "children" props => Lacks "key" props => Lacks "ref" props => String -> ({ render :: r -> JSX | props } -> Hook hooks r) -> Effect (ReactComponent { render :: r -> JSX | props })
Convert a hook to a render-prop component. The value returned from the
hook will be passed to the render
prop, a function from that value
to JSX
.
This function is useful for consuming a hook within a non-hook component.
#ReactChildren Source
data ReactChildren :: forall k. k -> Type
data ReactChildren a
#reactChildrenToArray Source
reactChildrenToArray :: forall a. ReactChildren a -> Array a
#reactChildrenFromArray Source
reactChildrenFromArray :: forall a. Array a -> ReactChildren a
#memo Source
memo :: forall props. Effect (ReactComponent props) -> Effect (ReactComponent props)
Prevents a component from re-rendering if its new props are referentially
equal to its old props (not value-based equality -- this is due to the
underlying React implementation).
Prefer memo'
for more PureScript-friendldy behavior.
#memo' Source
memo' :: forall props. (props -> props -> Boolean) -> Effect (ReactComponent props) -> Effect (ReactComponent props)
Similar to memo
but takes a function to compare previous and new props.
For example:
mkMyComponent :: Effect (ReactComponent { id :: Int })
mkMyComponent =
memo' eq do
reactComponent "MyComponent" \{ id } -> React.do
...
#useEffect Source
useEffect :: forall deps. Eq deps => deps -> Effect (Effect Unit) -> Hook (UseEffect deps) Unit
Runs the given effect when the component is mounted and any time the given dependencies change. The effect should return its cleanup function. For example, if the effect registers a global event listener, it should return an Effect which removes the listener.
useEffect deps do
timeoutId <- setTimeout 1000 (logShow deps)
pure (clearTimeout timeoutId)
If no cleanup is needed, use pure (pure unit)
or pure mempty
to return
a no-op Effect
useEffect deps do
logShow deps
pure mempty
#useLayoutEffect Source
useLayoutEffect :: forall deps. Eq deps => deps -> Effect (Effect Unit) -> Hook (UseLayoutEffect deps) Unit
Like useEffect
, but the effect is performed synchronously after the browser has
calculated layout. Useful for reading properties from the DOM that are not available
before layout, such as element sizes and positions. Prefer useEffect
whenever
possible to avoid blocking browser painting.
#useLayoutEffectOnce Source
useLayoutEffectOnce :: Effect (Effect Unit) -> Hook (UseLayoutEffect Unit) Unit
Like useLayoutEffect
, but the effect is only performed a single time per component
instance. Prefer useLayoutEffect
with a proper dependency list whenever possible!
#useLayoutEffectAlways Source
useLayoutEffectAlways :: Effect (Effect Unit) -> Hook (UseLayoutEffect Unit) Unit
Like useLayoutEffect
, but the effect is performed on every render. Prefer useLayoutEffect
with a proper dependency list whenever possible!
#UseLayoutEffect Source
data UseLayoutEffect t0 t1
#runReducer Source
runReducer :: forall state action. Reducer state action -> state -> action -> state
Run a wrapped Reducer
function as a normal function (like runFn2
).
Useful for testing, simulating actions, or building more complicated
hooks on top of useReducer
#useReducer Source
useReducer :: forall state action. state -> Reducer state action -> Hook (UseReducer state action) (state /\ (action -> Effect Unit))
Use mkReducer
to construct a reducer function.
#UseReducer Source
data UseReducer t0 t1 t2
#useContext Source
useContext :: forall a. ReactContext a -> Hook (UseContext a) a
#UseContext Source
data UseContext t0 t1
#useEqCache Source
useEqCache :: forall a. Eq a => a -> Hook (UseEqCache a) a
Cache an instance of a value, replacing it when eq
returns false
.
This is a low-level performance optimization tool. It can be useful
for optimizing a component's props for use with memo
, where
JavaScript instance equality matters.
#UseEqCache Source
data UseEqCache t0 t1
#useDebugValue Source
useDebugValue :: forall a. a -> (a -> String) -> Hook (UseDebugValue a) Unit
Use this hook to display a label for custom hooks in React DevTools
#UseDebugValue Source
data UseDebugValue t0 t1
#UnsafeReference Source
#displayName Source
displayName :: forall props. ReactComponent props -> String
Retrieve the Display Name from a ReactComponent
. Useful for debugging and improving
error messages in logs.
See also: component
Re-exports from Data.Tuple.Nested
#(/\) Source
Operator alias for Data.Tuple.Tuple (right-associative / precedence 6)
Shorthand for constructing n-tuples as nested pairs.
a /\ b /\ c /\ d /\ unit
becomes Tuple a (Tuple b (Tuple c (Tuple d unit)))
#type (/\) Source
Operator alias for Data.Tuple.Tuple (right-associative / precedence 6)
Shorthand for constructing n-tuple types as nested pairs.
forall a b c d. a /\ b /\ c /\ d /\ Unit
becomes
forall a b c d. Tuple a (Tuple b (Tuple c (Tuple d Unit)))
Re-exports from React.Basic
#ReactContext Source
data ReactContext t0
#ReactComponent Source
data ReactComponent t0
Represents a traditional React component. Useful for JavaScript interop and FFI. For example:
foreign import ComponentRequiringJSHacks :: ReactComponent { someProp :: String }
See also: element
, toReactComponent
#JSX Source
data JSX
Represents rendered React VDOM (the result of calling React.createElement
in JavaScript).
JSX
is a Monoid
:
append
- Merge two
JSX
nodes usingReact.Fragment
.
- Merge two
mempty
- The
empty
node; renders nothing.
- The
Hint: Many useful utility functions already exist for Monoids. For example,
guard
can be used to conditionally render a subtree of components.
Instances
#provider Source
provider :: forall a. ReactContext a -> a -> Array JSX -> JSX
Create a provider JSX
given a context value and children.
See also: createContext
, consumer
#elementKeyed Source
elementKeyed :: forall props. ReactComponent (Record props) -> { key :: String | props } -> JSX
Create a JSX
node from a ReactComponent
, by providing the props and a key.
See also: ReactComponent
, element
, React's documentation regarding the special key
prop
#element Source
element :: forall props. ReactComponent (Record props) -> Record props -> JSX
Create a JSX
node from a ReactComponent
, by providing the props.
See also: ReactComponent
, elementKeyed
#createContext Source
createContext :: forall a. a -> Effect (ReactContext a)
Create a ReactContext
given a default value. Use provider
and consumer
to provide and consume context values. Alternatively, use contextProvider
and contextConsumer
directly if a ReactComponent
is required for interop.
See also: provider
, consumer
, React's documentation regarding Context
#contextProvider Source
contextProvider :: forall a. ReactContext a -> ReactComponent { children :: Array JSX, value :: a }
#contextConsumer Source
contextConsumer :: forall a. ReactContext a -> ReactComponent { children :: a -> Array JSX }
#consumer Source
consumer :: forall a. ReactContext a -> (a -> Array JSX) -> JSX
Create a consumer JSX
from a context value to children.
See also: createContext
, producer
Re-exports from React.Basic.Hooks.Internal
#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
IxMonad 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) => Monad (Render x y)
(TypeEquals x y, Semigroup a) => Semigroup (Render x y a)
(TypeEquals x y, Monoid a) => Monoid (Render x y a)
#Hook Source
type Hook :: (Type -> Type) -> Type -> Type
type Hook (newHook :: Type -> Type) a = forall hooks. Render hooks (newHook hooks) a
Type alias for Render representing a hook.
The newHook
argument is a type constructor which takes a set of existing
effects and generates a type with a new set of effects (produced by this
hook) stacked on top.
#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
!
#unsafeHook Source
unsafeHook :: forall newHook a. 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!
#coerceHook Source
coerceHook :: forall hooks oldHook newHook a. 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
...
#type (&) Source
Operator alias for React.Basic.Hooks.Internal.HookApply (left-associative / precedence 0)
Applies a new hook to a hook chain, with the innermost hook as the left argument. This allows hook chains to be written in reverse order, aligning them with the order they appear when actually used in do-notation.
type UseCustomHook hooks = UseEffect String (UseState Int hooks)
type UseCustomHook' = UseState Int & UseEffect String