Module

React.Basic.Hooks

Package
purescript-react-basic-hooks
Repository
spicydonuts/purescript-react-basic-hooks

#component Source

component :: forall props hooks. 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.

#componentWithChildren Source

componentWithChildren :: forall children props hooks. 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.

#ReactChildren Source

#memo Source

memo :: forall props. Effect (ReactComponent props) -> Effect (ReactComponent props)

#UseState Source

data UseState :: Type -> Type -> Type

#useState Source

useState :: forall state. state -> Hook (UseState state) (state /\ ((state -> state) -> Effect Unit))

#UseEffect Source

data UseEffect :: Type -> Type -> Type

#useEffect Source

useEffect :: forall key. Eq key => key -> Effect (Effect Unit) -> Hook (UseEffect key) Unit

The effect will be run when the component is mounted, and the effect returned from the function will be run on cleanup

#UseLayoutEffect Source

#useLayoutEffect Source

useLayoutEffect :: forall key. Eq key => key -> Effect (Effect Unit) -> Hook (UseLayoutEffect key) Unit

#UseReducer Source

data UseReducer :: Type -> Type -> Type -> Type

#useReducer Source

useReducer :: forall action state. state -> (state -> action -> state) -> Hook (UseReducer state action) (state /\ (action -> Effect Unit))

#UseRef Source

data UseRef :: Type -> Type -> Type

#readRef Source

readRef :: forall a. Ref a -> Effect a

#readRefMaybe Source

readRefMaybe :: forall a. Ref (Nullable a) -> Effect (Maybe a)

#writeRef Source

writeRef :: forall a. Ref a -> a -> Effect Unit

#renderRef Source

renderRef :: forall a. Ref a -> Pure a

#renderRefMaybe Source

renderRefMaybe :: forall a. Ref (Nullable a) -> Pure (Maybe a)

#useRef Source

useRef :: forall a. a -> Hook (UseRef a) (Ref a)

#UseContext Source

data UseContext :: Type -> Type -> Type

#useContext Source

useContext :: forall a. ReactContext a -> Hook (UseContext a) a

#UseMemo Source

data UseMemo :: Type -> Type -> Type -> Type

#useMemo Source

useMemo :: forall a key. Eq key => key -> (Unit -> a) -> Hook (UseMemo key a) a

#UseCallback Source

data UseCallback :: Type -> Type -> Type -> Type

#useCallback Source

useCallback :: forall a key. Eq key => key -> a -> Hook (UseCallback key a) a

#UseEqCache Source

data UseEqCache :: Type -> Type -> Type

#useEqCache Source

useEqCache :: forall a. Eq a => a -> Hook (UseCallback a a) a

#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

#Ref Source

data Ref :: Type -> Type

A React Ref, as created by React.createRef

#ReactContext Source

#ReactComponent Source

data ReactComponent :: Type -> Type

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 :: Type

Represents rendered React VDOM (the result of calling React.createElement in JavaScript).

JSX is a Monoid:

  • append
    • Merge two JSX nodes using React.Fragment.
  • mempty
    • The empty node; renders nothing.

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

#keyed Source

keyed :: String -> JSX -> JSX

Apply a React key to a subtree. React-Basic usually hides React's warning about using key props on components in an Array, but keys are still important for any dynamic lists of child components.

See also: React's documentation regarding the special key prop

#fragment Source

fragment :: Array JSX -> JSX

Render an Array of children without a wrapping component.

See also: JSX

#empty Source

empty :: JSX

An empty JSX node. This is often useful when you would like to conditionally show something, but you don't want to (or can't) modify the children prop on the parent node.

See also: JSX, Monoid guard

#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.

render self =
  R.div_
  [ R.button
    { onClick: capture_ $ self.setState \s -> s { counter = s.counter + 1 }
    , children: [ R.text "Tick!" ]
    }
  , provider countContext self.state.counter
    [ consumer countContext \counter ->
       [ R.text $ "Ticks: " <> (show counter)
       ]
    ]
  ]

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.

Instances

#Pure Source

type Pure a = forall hooks. Render hooks hooks a

Discards

#Hook Source

type Hook (newHook :: Type -> Type) a = forall hooks. Render hooks (newHook hooks) a

#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 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 key. useAff tracks both the key 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 keys as they use Eq and a reorder would allow React to pass incorrect types into the eq function!

#discard Source

discard :: forall m z y x b a. IxBind m => m x y a -> (a -> m y z b) -> m x z b

Exported for use with qualified-do syntax

#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 key a hooks
  = UseEffect key (UseState (Result a) hooks)

useAff :: ... -> Hook (UseAff key a) (Result a)
useAff key aff = React.do
  ...

coerceHook allows the same code to safely export a newtype instead, hiding the internal implementation:

newtype UseAff key a hooks
  = UseAff (UseEffect key (UseState (Result a) hooks))

derive instance ntUseAff :: Newtype (UseAff key a hooks) _

useAff :: ... -> Hook (UseAff key a) (Result a)
useAff key aff = coerceHook React.do
  ...

#bind Source

bind :: forall m z y x b a. IxBind m => m x y a -> (a -> m y z b) -> m x z b

Exported for use with qualified-do syntax