reacl2.core

Reacl core functionality.

*app-state-map*

dynamic

*local-state-map*

dynamic

->Effects

(->Effects args)

Positional factory function for reacl2.core/Effects.

->EmbedAppState

(->EmbedAppState app-state embed)

Positional factory function for reacl2.core/EmbedAppState.

->KeywordEmbedder

(->KeywordEmbedder keyword)

Positional factory function for reacl2.core/KeywordEmbedder.

->Options

(->Options map)

Positional factory function for reacl2.core/Options.

class

macro

(class ?name & ?stuff)

Create a Reacl class.

The syntax is

(reacl.core/class <name> [<this-name> [<app-state-name>]] [<param> ...]
  render <renderer-exp>
  [local-state [<name> <initial-state-exp>]
  [local [<local-name> <local-expr>]]
  [handle-message <messager-handler-exp>]
  [<lifecycle-method-name> <lifecycle-method-exp> ...])

<name> is a name for the class, for debugging purposes.

A number of names are bound in the various expressions in the body of reacl.core/class:

  • <this-name> is bound to the component object itself
  • <app-state-name> is bound to the global application state
  • <local-state-name> is bound to the component-local state
  • the <param> … names are the explicit arguments of instantiations

A local clause allows binding additional local variables upon instantiation. The syntax is analogous to let.

<renderer-exp> is an expression that renders the component, and hence must return a virtual dom node.

The handle-message function accepts a message sent to the component via reacl.core/send-message!. It’s expected to return a value specifying a new application state and/or component-local state, via reacl.core/return.

A class can be invoked to yield a component as a function as follows:

(<class> <app-state> <reaction> <arg> ...)

In this invocation, the value of <app-state> will be the initial app state, <reaction> must evaluate to a reaction (see reacl.core.reaction) that gets invoked when the component’s app state changes, and the <arg>s get evaluated to the <param>s.

A lifecycle method can be one of:

component-will-mount component-did-mount component-will-receive-args should-component-update? component-will-update component-did-update component-will-unmount

These correspond to React’s lifecycle methods, see here:

http://facebook.github.io/react/docs/component-specs.html

(component-will-receive-args is similar to componentWillReceiveProps.)

Each right-hand-side <lifecycle-method-exp>s should evaluate to a function. The arguments, which slightly differ from the corresponding React methods, can be seen in the following list:

(component-will-mount) The component can send itself messages in this method, or optionally return a new state via reacl.core/return. If that changes the state, the component will only render once.

(component-did-mount) The component can update its DOM in this method. It can also return a new state via reacl.core/return.

(component-will-receive-args next-arg1 next-arg2 ...) The component has the chance to update its local state in this method by sending itself a message or optionally return a new state via reacl.core/return.

(should-component-update? next-app-state next-local-state next-arg1 next-arg2 ...) This method should return if the given new values should cause an update of the component (if render should be evaluated again). If it’s not specified, a default implementation will do a (=) comparison with the current values. Implement this, if you want to prevent an update on every app-state change for example.

(component-will-update next-app-state next-local-state next-arg1 next-arg2 ...) Called immediately before an update.

(component-did-update prev-app-state prev-local-state prev-arg1 prev-arg2 ...) Called immediately after an update. The component can update its DOM here.

(component-will-unmount) The component can cleanup it’s DOM here for example.

Example:

(defrecord New-text [text]) (defrecord Submit []) (defrecord Change [todo])

(reacl/defclass to-do-app this app-state []

local-state [local-state ""]

render
(dom/div
 (dom/h3 "TODO")
 (dom/div (map (fn [todo]
                 (dom/keyed (str (:id todo))
                            (to-do-item
                             todo
                             (reacl/reaction this ->Change)
                             this)))
               (:todos app-state)))
 (dom/form
  {:onsubmit (fn [e _]
               (.preventDefault e)
               (reacl/send-message! this (Submit.)))}
  (dom/input {:onchange 
              (fn [e]
                (reacl/send-message!
                 this
                 (New-text. (.. e -target -value))))
              :value local-state})
  (dom/button
   (str "Add #" (:next-id app-state)))))

handle-message
(fn [msg]
  (cond
   (instance? New-text msg)
   (reacl/return :local-state (:text msg))

   (instance? Submit msg)
   (let [next-id (:next-id app-state)]
     (reacl/return :local-state ""
                   :app-state
                   (assoc app-state
                     :todos
                     (concat (:todos app-state)
                             [(Todo. next-id local-state false)])
                     :next-id (+ 1 next-id))))

   (instance? Delete msg)
   (let [id (:id (:todo msg))]
     (reacl/return :app-state
                   (assoc app-state
                     :todos 
                     (remove (fn [todo] (= id (:id todo)))
                             (:todos app-state)))))

   (instance? Change msg)
   (let [changed-todo (:todo msg)
         changed-id (:id changed-todo)]
     (reacl/return :app-state
                   (assoc app-state
                     :todos (mapv (fn [todo]
                                    (if (= changed-id (:id todo) )
                                      changed-todo
                                      todo))
                                  (:todos app-state))))))))

create-class

(create-class display-name compat-v1? mixins has-app-state? compute-locals fns)

defclass

macro

(defclass ?name & ?stuff)

Define a Reacl class, see class for documentation.

The syntax is

(reacl.core/defclass <name> [<this-name> [<app-state-name> [<local-state-name>]]] [<param> ...]
  render <renderer-exp>
  [initial-state <initial-state-exp>]
  [<lifecycle-method-name> <lifecycle-method-exp> ...]
  [handle-message <messager-handler-exp>]

  <event-handler-name> <event-handler-exp> ...)

This expands to this:

(def <name>
  (reacl.core/class <name> [<this-name> [<app-state-name> [<local-state-name>]]] [<param> ...]
    render <renderer-exp>
    [initial-state <initial-state-exp>]
    [<lifecycle-method-name> <lifecycle-method-exp> ...]
    [handle-message <messager-handler-exp>]

    <event-handler-name> <event-handler-exp> ...))

dispatch-action!

(dispatch-action! comp action)

Dispatch an action from a Reacl component.

You can call this from a regular event handler.

Effects

This marks effects returned by an invocation.

The args field contains the list of arguments to return.

Used internally by return.

EmbedAppState

extract-initial-app-state

(extract-initial-app-state this)

Extract initial applications state from a Reacl component.

handle-returned!

(handle-returned! comp ret)

Handle all effects described in a Returned object.

has-class?

(has-class? clazz element)

Find out if an element was generated from a certain Reacl class.

instantiate-toplevel

(instantiate-toplevel clazz frst & rst)

For testing purposes mostly.

invoke-reaction

(invoke-reaction this reaction value)

Invokes the given reaction with the given message value (usually an app-state).

KeywordEmbedder

map->Effects

(map->Effects G__3720)

Factory function for reacl2.core/Effects, taking a map of keywords to field values.

map->EmbedAppState

(map->EmbedAppState G__3641)

Factory function for reacl2.core/EmbedAppState, taking a map of keywords to field values.

map->KeywordEmbedder

(map->KeywordEmbedder G__3650)

Factory function for reacl2.core/KeywordEmbedder, taking a map of keywords to field values.

map->Options

(map->Options G__3667)

Factory function for reacl2.core/Options, taking a map of keywords to field values.

mixin

macro

(mixin & ?stuff)

Define a mixin. Mixins let you provide additional lifecycle method expressions that you can mix into your components.

The syntax is

(reacl.core/mixin [<this> [<app-state> [<local-state>]]] [<param> ...]
  [<lifecycle-method-name> <lifecycle-method-exp> ...])

In order to use the mixin you can use the mixins clause in defclass

(reacl.core/defclass foo ...
  mixins [(<your-mixin-var> [<param> ...])]
  ...)

The lifecycle method expressions in the mixins will be called in order. Only after all mixin lifecycle methods have been handled the component’s own lifecycle method will be called.

no-reaction

Use this as a reaction if you don’t want to react to an app-state change.

opt

(opt & {:as mp})

Create options for component instantiation.

Takes keyword arguments :reaction, :embed-app-state, :reduce-action.

  • :reaction must be a reaction to an app-state change, typically created via reaction, no-reaction, or pass-through-reaction. -
  • :embed-app-state can be specified as an alternative to :reaction and specifies, that the app state of this component is embedded in the parent component’s app state. This must be a function of two arguments, the parent app state and this component’s app-state. It must return a new parent app state.
  • :reduce-action takes arguments [app-state action] where app-state is the app state of the component being instantiated, and action is an action. This should call return to handle the action. By default, it is a function with body (return :action action) returning the action unchanged. This is called on every action generated by the child component. Local-state changes through this function are ignored.

opt-handle-effects!

(opt-handle-effects! component v)

Options

Optional arguments for instantiation.

pass-through-reaction

(pass-through-reaction component)

Use this if you want to pass the app-state as the message.

component must be the component to send the message to

react-class

(react-class clazz)

Extract the React class from a Reacl class.

reaction

(reaction component make-message & args)

A reaction that says how to deal with a new app state in a subcomponent.

  • component component to send a message to
  • make-message function to apply to the new app state and any additional args, to make the message.

Common specialized reactions are no-reaction and pass-through-reaction.

render-component

(render-component element clazz & rst)

Instantiate and render a component into the DOM.

  • element is the DOM element
  • clazz is the Reacl class
  • opts is an object created with opt
  • app-state is the application state
  • args is a seq of class arguments

return

(return & args)

Return state from a Reacl event handler.

Has two optional keyword arguments:

  • :app-state is for a new app state.
  • :local-state is for a new component-local state.
  • :action is for an action

A state can be set to nil. To keep a state unchanged, do not specify that option, or specify the value reacl.core/keep-state.

send-message!

(send-message! comp msg)

Send a message to a Reacl component.

Returns the Returned object returned by the message handler.