All arguments allowed
2014-02-15If it looks like a function…
Calling a component in Reagent looks a lot like a function call. Now it also works like one.
Before 0.4.0, component functions were always called with three arguments: a map of attributes, a vector of ”children”, and the current React component.
This was confusing, and an unnecessary limitation, so now component functions get exactly the same arguments you pass to them.
In other words, you can now do this:
Source
(defn hello-component [name] [:p "Hello, " name "!"]) (defn say-hello [] [hello-component "world"])
In the above example, it wouldn’t make any difference at
all if hello-component
had been called as a
function, i.e with parentheses instead of brackets (except
for performance, since components are cached between renders
if the arguments to them don’t change).
But there is one drawback: component function no longer
receives the ”current component” as a parameter. Instead
you’ll have to use reagent.core/current-component
in order to get that. Beware that current-component
is only valid in component
functions, and must be called outside of e.g event handlers
and for
expressions, so it’s safest to always
put the call at the top, as in my-div
here:
Source
(ns example (:require [reagent.core :as r]))(defn my-div [] (let [this (r/current-component)] (into [:div.custom (r/props this)] (r/children this)))) (defn call-my-div [] [:div [my-div "Some text."] [my-div {:style {:font-weight 'bold}} [:p "Some other text in bold."]]])
Note: r/props
and r/children
correspond to React’s this.props
and this.props.children
,
respectively. They may be convenient to use when wrapping
native React components, since they follow the same
conventions when interpreting the arguments given.
Other news in 0.4.0
- React has been updated to version 0.9.0.
- You can now use any object that satisfies
ifn?
as a component function, and not just plain functions. That includes functions defined withdeftype
,defrecord
, etc, as well as collections like maps. reagent.core/set-state
andreagent.core/replace-state
are now implemented using anreagent.core/atom
, and are consequently async.- Keys associated with items in a seq (e.g ”dynamic
children” in React parlance) can now be specified with
meta-data, as well as with a
:key
item in the first parameter as before. In other words, these two forms are now equivalent:^{:key foo} [:li bar]
and[:li {:key foo} bar]
. - Performance has been improved even further. For
example, there is now practically no overhead for
tracking derefs in components that don’t use
atom
s. Allocations and memory use have also been reduced. - Intro and examples have been tweaked a little to take advantage of the new calling conventions.
New svg example
There is also a new, elegant and simple example of using svg with Reagent, written by Jonas Enlund. It also shows how you can use Reagent’s new calling convensions, and looks like this: