-
Notifications
You must be signed in to change notification settings - Fork 364
Documentation
The Om life cycle protocols map more or less directly to the life cycle API present in Facebook's React.
Om component functions return reify
instances that implement the Om
life cycle protocols. When this
is used in a lifecycle protocol it refers
to the reify instance. As a rule of thumb it is not needed and can be discarded.
(defn my-widget [data owner]
(reify
om/IRender
(render [_]
(dom/h1 nil "Hello world!"))))
It's important to understand the my-widget
will be called many
times. Thus it's an anti-pattern to wrap reify
in a let
to
allocate stateful entities like core.async channels. Stateful entities
should be stored in component local state - om.core/IInitState
or
om.core/IWillMount
are good places to do this.
(defprotocol IInitState
(init-state [this]))
Called only once on an Om component. Implementations should return a map of initial state.
(defn my-widget [data owner]
(reify
om/IInitState
(init-state [_]
{:text "Hello world!"})
om/IRenderState
(render-state [_ state]
(dom/h1 nil (:text state)))))
(defprotocol IWillMount
(will-mount [this]))
Called once when the component is about to be mounted into the DOM. A useful place to establish persistent information and control like core.async channels and go loops.
(defprotocol IDidMount
(did-mount [this]))
Called once when the component has been mounted into the DOM. The DOM node associated with this component can be retrieved by using om.core/get-node
.
This is a good place to initialize persistent information and control that needs the DOM to be present.
(defprotocol IShouldUpdate
(should-update [this next-props next-state]))
You should only implement this if you really know what you're doing. Even then you probably shouldn't.
Implementations should return a boolean value. If true then the
component's om.core/IRender
or om.core/IRenderState
implementation
will be called. This provides the opportunity to prevent components
from re-rendering in response to certain changes in app (props) or local
state. Please note that preventing components from re-rendering
in response to props or state change could result in the DOM being out
of sync with application or local state.
next-props
is the next application state that the component is
associated with. next-state
is the next component local state, it is
always a map.
In your implementation if you wish to detect prop transitions you
must use om.core/get-props
to get the previous props. This is because your component
constructor function is called with the updated props.
(defprotocol IWillReceiveProps
(will-receive-props [this next-props]))
Not called on the first render, will be called on all subsequent renders. This is a good place to detect app state changes and make updates to local component state using om/set-state! or om/update-state!.
next-props
is the next application state associated with this
component.
In your implementation if you wish to detect prop transitions you
must use om.core/get-props
to get the previous props. This is
because your component constructor function is called with the
updated props.
(defprotocol IWillUpdate
(will-update [this next-props next-state]))
Not called on the first render, will be called on all subsequent renders. This is a good place to detect and act on state transitions.
next-props
is the next application state associated with this
component. next-state
is the next component local state, it is
always a map.
In your implementation if you wish to detect prop transitions you
must use om.core/get-props
to get the previous props. This is
because your component constructor function is called with the
updated props.
Note:: You cannot update local component state in this method. If you wish to change local state in response to prop changes use IWillReceiveProps.
(defprotocol IDidUpdate
(did-update [this prev-props prev-state]))
Called when React has rendered the component into the
DOM. prev-props
is the previous application state associated with
this component. prev-state
is the previous component local state, it
is always a map.
(defprotocol IRender
(render [this]))
Called on all changes to application state or component local state. Must return an Om component, a React component, or a some value that React knows how to render.
If you implement om.core/IRender
you should not implement
om.core/IRenderState
.
(defprotocol IRenderState
(render-state [this state]))
The only difference between om.core/IRender
and
om.core/IRenderState
is that IRenderState
implementations get the
state as an argument. state
is always a map, you can use destructuring.
If you implement om.core/IRenderState
you should not implement
om.core/IRender
.
(defprotocol IDisplayName
(display-name [this]))
Return a string name to be used for debugging. The Chrome React Developer Tools extension uses this to name the components.
(defprotocol IWillUnmount
(will-unmount [this]))
Called immediately before a component is unmounted from the DOM.
Perform any necessary cleanup in this method, such as invalidating timers or cleaning up any DOM elements that were created in om.core/IDidMount
.
(defn get-props [owner]
...)
owner
is the backing Om component. om.core/get-props
returns the
cursor into the application state associated with the Om
component. A cursor is a piece of the application state that knows
how to update itself.
(defn get-state
([owner] ...)
([owner korks] ...))
owner
is the backing Om component. korks
is a key or sequence of
keys. Will return the specified piece of component local state. Will
always return pending state.
(defn get-shared
([owner] ...)
([owner korks] ...))
owner
is the backing Om component. korks
is a key or sequence of
keys. It will return data that is shared across the entire render tree.
You can set global shared data with om.core/root
.
(defn root
([f value options] ...))
f
is a function returning an instance of IRender
or IRenderState
.
f
takes two arguments, a root cursor on the application state and
the backing Om component for the root. value
is either a tree of
associative ClojureScript data structures or an atom wrapping a tree
of associative ClojureScript data structures.
options
is a map containing any key allowed to om.core/build
.
Additionally the following keys are allowed/required:
-
:target
(required) -
:shared
(optional) in order to provide global services -
:tx-listen
a function that will listen in on transactions, should take 2 arguments - the first a map containing the path, old and new state at path, old and new global state, and transaction tag if provided. -
:path
to specify the path of the cursor into app-state (see #72) -
:instrument
a function of three arguments that if provided will intercept all calls toom.core/build
. The function arguments correspond exactly to the three argument arity ofom.core/build
om.core/root
is idempotent. You may safely call it multiple
times. Only one Om render loop is ever allowed on a particular DOM
target.
(om.core/root
(fn [app-state owner]
(reify
om.core/IRender
(render [_]
(dom/h1 nil (:text app-state)))))
{:text "Hello world!"}
{:target (. js/document getElementById "my-app")})
(defn build
([f cursor] ...)
([f cursor m] ...))
Constructs an Om component. f
must be a function that returns an
instance of om.core/IRender
or om.core/IRenderState
. f
must take
two arguments - a cursor and the backing Om component usually referred
to as the owner. f
can take a third argument if :opts
is
specified in m
. The component is identified by the function f
. Changing
f
to a different function will construct a new component, while changing
the return value will not change component.
cursor
should be an Om cursor onto the application state. m
is an
optional map of options.
Only the following keys are allowed in m
.
:key
- a keyword that will be used to lookup a value in cursor
to
be used as a React key.
:react-key
- a value to use as a React key.
:fn
- a function to apply to cursor
before invoking f
.
:init-state
- a map of initial state to set on the component.
:state
- a map of state to merge into the component.
:opts
- a map of side information that is neither a cursor onto the
application state nor component local state.
(defn build*
([f cursor] ...)
([f cursor m] ...))
Identical to om.core/build
except cannot be intercepted by the
:instrument
argument provided to om.core/root
. Needed to avoid
infinite loops in components constructed via :instrument
.
(defn build-all
([f xs] ...)
([f xs m] ...)
Conceptually the same as om.core/build
, the only difference is that
it returns a sequence of Om components. xs
is a sequence of
cursors. f
and m
are the same as om.core/build
.
(defn transact!
([cursor f] ...)
([cursor korks f])
([cursor korks f tag]))
The primary way to transition application state. cursor
is an Om
cursor into the application state. f
is a function that will receive
the specified piece of application state. korks
is an optional
key or sequence of keys to access in the cursor. om.core/transact!
can be given additional args to pass to f
. tag
is optional
information to tag the transaction. tag
should be either a keyword
or a vector whose first element is a keyword
.
(transact! cursor :text (fn [_] "Changed this!"))
(defn update!
([cursor v] ...)
([cursor korks v] ...)
([cursor korks v tag] ...))
Similar to om.core/transact!
but just sets a cursor to a new value,
analagous to reset!
for atoms.
(update! cursor [:text] "Changed this!")
(defn get-node
([owner ref] ...)
([owner] ...))
owner
is the backing Om component. ref
is a JavaScript String that
references a DOM node. This functionality is identical to the
ReactComponent.getDOMNode
in React.
(defn set-state!
([owner korks v] ...))
Sets component local state. owner
is the backing Om
component. korks
is a key or sequences of keys. v
is the value to
set. Will trigger a Om re-render.
(defn update-state!
([owner f] ...)
([owner korks f] ...))
Takes a pure owning component, an optional sequential list of keys and a function to transition the state of the component. Conceptually analogous to React setState
. Will schedule an Om re-render.
(defn refresh! [owner]
...)
Utility to re-render an owner. Delegates to update-state!
.
(defn get-render-state
([owner] ...)
([owner korks] ...))
Returns rendered component local state. owner
is the backing Om
component. korks
is an optional key or sequences of keys. Similar to
om.core/get-state
except always returns the rendered state. Useful
for detecting state transitions.
(defn rendering? []
...)
Return true if in the React rendering phase. Useful in IWillMount
when establishing code that may run sync with render the first time
and async thereafter.
The dom functions map directly to the DOM api presented by React. For
example React.DOM.div
becomes om.dom/div
. The arguments are exactly
the same as React, the first argument is props
, all subsequent
arguments are children
.
For a list of supported props
see React's supported DOM attributes and React's special attributes. As an example of the special attributes, the following code will create a div
component that contains raw HTML:
(om.dom/div (clj->js {:dangerouslySetInnerHTML {:__html "<b>Bold!</b>"}})
nil)
Be careful! The attribute is well-named: this is potentially dangerous and should be used with caution.
(defn render-to-str [c]
...)
Equivalent to React.renderComponentToString
. For example:
(dom/render-to-str (om/build some-widget data))