Home

Awesome

purescript-dispatcher-react

A simple action dispatcher for purescript-react.

bower install purescript-dispatcher-react --save

The motivation behind this library are given in a comparison with some existing libraries. In summary:

Documentation

Module documentation is published on Pursuit.

Examples

Simple toggle button example:

data Action = ToggleState

toggler :: ReactElement
toggler = createFactory (createComponent { on: false } render (effEval eval)) unit
  where

  render state (DispatchEff d) =
    div'
      [ h1'
          [ text "Toggle Button" ]
      , button
          [ onClick $ d \_ -> ToggleState ]
          [ text (if state.on then "On" else "Off") ]
      ]
  eval ToggleState = modifyState (\state -> { on: not state.on })

Ajax example

data Action = FetchMovie

newtype Movie = Movie { title :: String, poster :: String}
instance decodeMovie :: Decode Movie where
  decode f = do
    title <- readProp "Title" f >>= decode
    poster <- readProp "Poster" f >>= decode
    pure $ Movie { title, poster }

type State = {movie::Maybe Movie}

ajax :: {title::String} -> ReactElement
ajax = createFactory $ createLifecycleComponent (didMount FetchMovie) {movie:Nothing} render eval
  where
    render {movie} = div' $ maybe nomovie showMovie movie
      where
      showMovie (Movie {title, poster}) = [ h1' [ text title ], img [src poster] [] ]
      nomovie = [ h1' [ text "Waiting for movie response" ] ]

    eval FetchMovie = do
      {title} <- getProps
      s <- lift $ get $ "http://www.omdbapi.com/?t=" <> encodeURIComponent title <> "&y=&plot=short&r=json"
      let movie = either (const $ Nothing) Just $ runExcept $ decodeJSON s.response
      modifyState _ {movie=movie}

Lifecycle example

data Action = Init | Destroy

lifecycleComponent :: forall eff. {onClick :: Unit -> Eff eff Unit} -> ReactElement
lifecycleComponent = createFactory (createLifecycleComponent (didMount Init *> willUnmount Destroy) {} render eval) where
  render s (ReactProps p) (DispatchEff d) = div' [
        h1' [ text "I am alive" ]
      , button [onClick $ d \_ -> p.onClick unit] [ text "Click to kill me"]
    ]
  eval Init = log "I am alive"
  eval Destroy = log "I am dead"


lifecycleParent :: ReactElement
lifecycleParent = createFactory (createComponent {show:true} render unit) unit where
  render {show} (DispatchEff d) =
    if show
    then lifecycleComponent {onClick: d $ effEval \_ ->  modifyState _ {show=false}}
    else div' [ text "You killed it. Check the console" ]

React native movie example