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:
(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:
(ns example (:require [reagent.core :as r :refer [atom]])) (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.
ifn?
as a component function, and not just
plain functions. That includes functions defined with deftype
, defrecord
, etc, as well
as collections like maps.reagent.core/set-state
and reagent.core/replace-state
are now implemented
using an reagent.core/atom
, and are
consequently async.: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]
.atom
s. Allocations and memory use have also
been reduced.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: