This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-05-08
Channels
- # architecture (20)
- # beginners (140)
- # cider (155)
- # cljsjs (1)
- # cljsrn (29)
- # clojure (53)
- # clojure-dev (9)
- # clojure-italy (40)
- # clojure-nl (13)
- # clojure-poland (4)
- # clojure-russia (8)
- # clojure-uk (51)
- # clojurescript (74)
- # cursive (36)
- # data-science (1)
- # datomic (3)
- # emacs (14)
- # fulcro (11)
- # graphql (2)
- # java (21)
- # javascript (2)
- # jobs (3)
- # nrepl (7)
- # off-topic (18)
- # om-next (1)
- # onyx (9)
- # portkey (8)
- # re-frame (72)
- # reagent (64)
- # reitit (4)
- # remote-jobs (1)
- # rum (1)
- # schema (1)
- # shadow-cljs (49)
- # slack-help (1)
- # spacemacs (8)
- # specter (7)
- # tools-deps (27)
- # vim (28)
what's your solution for autocomplete component these days? sometimes I use material-ui but what if I don't want to depend on it?
I've never tried, but closure library seems to have some autocomplete functionality: - https://google.github.io/closure-library/source/closure/goog/demos/ - https://google.github.io/closure-library/api/goog.ui.ac.AutoComplete.html
thanks, maybe it doesn't have "chips" kind of functionality? So that you can easily remove items by clicking
Hey! How do I do
[:div
(if x?
[[:div]
[:div]]
[[:span]
[:span]])]
without additional divs?By using react fragments: https://github.com/reagent-project/reagent/blob/master/CHANGELOG.md#080-2018-04-19
Or just list
: [:div (list [:div] [:div])
, works the same as sequences (`for`, map
) so you'll need to add React keys
Fragments are needed when you want to return multiple events from component directly
(defn foo [] (list [:div] [:div]))
doesn't work, but
(defn bar [] [:<> [:div] [:div]))
works
Also, you could use into
:
(into [:div] (if x? [[:div] [:div]] [[:span] [:span]]))
might be simplest, definitely no need to use React keys in this case as this is effectively same as writing [:div [:div] [:div]]
tried to use (list ..)
- caught exception TypeError: Cannot convert a Symbol value to a string
Reminder: Fragments are for cases where one wants to return multiple elements from a component: https://reactjs.org/docs/fragments.html
Inside components, you can use into
, list
, for
, map
I never quite understood how reagent handles the differences between
[:div (gen-html :one)]
and [:div [gen-html :one]]
so from my understanding the behave the same way, and it's simply done to delay the evaluation (I guess)
but in many cases it also behaves in the same way
and can it be nested anyway? would
[:div [transform [gen-html :one] :two]]
make sense as well?
what's the lower level function to call to just see what gets generated in the REPL?
@andrea.crotti There are docs at https://github.com/reagent-project/reagent/blob/master/docs/UsingHiccupToDescribeHTML.md but that may not really answer you
If you use vectors (square brackets) instead of lists (parentheses), then it is interpreted as a hiccup form. If the hiccup has a symbol as first element, then that symbol’s associated fn will be used as the render fn for the component.
However, since you used a vector, Reagent can avoid calling the fn until it needs to. If the arguments haven’t changed in value, then it won’t be called - that sort of optimizatoin
If you use a list form, with parentheses, then it will be called naturally because Reagent isn’t done with macros, so evaluation order is the same as any other Clojure code
In that case, Reagent never gets the opportunity to step in and avoid the render fn call to avoid the nested hiccup generation
ok yes thanks, I was digging for some code that actually can render the HTML directly without writing into the DOM
and I think it's this function?
(defn as-element [x]
(cond (js-val? x) x
(vector? x) (vec-to-elem x)
(seq? x) (if (dev?)
(expand-seq-check x)
(expand-seq x))
(named? x) (name x)
(satisfies? IPrintWithWriter x) (pr-str x)
:else x))
But you probably have to also understand reagent.impl.component/as-class
a bit (which is called in reag-element
, to understand the mechanism that the vector hiccup forms may avoid calling the render fn
Your component fn, say my-fn
above, is used to generate a React style class that implements various life cycle methods for you.
The shouldComponentUpdate
is the main one of interest https://github.com/reagent-project/reagent/blob/master/src/reagent/impl/component.cljs#L160
In reag-element
, you’ll notice it calls (react/createElement c jsprops)
. This treats the hiccup form as a React element, and therefore goes through those life cycle methods.
If you called it without hiccup, with a list/parentheses, it would have just called your fn as a normal fn with no potential to avoid recomputing the nested renders.
Yep, I was just dumping the details since I thought that there was interest in that particular question. Your phrase nicely captures the idea.
oh yea, there’s enough magic to reagent i think it is really helpful to understand how it works.
there are still things I don’t get, like how reagent caches the react component. it looks like it stores the react component on the actual hiccup datastructure or something like that, but i can’t figure it out for the life of me (not without a debugger)
@lee.justin.m Yeah, I have found going through the impl to be a useful exercise
To cache the component class on a reagent tag where the symbol is just a function, I thought it just sticks the cached version on a keyword on the underlying JS function object
I actually am more familiar with clj than cljs and to me it seems crazy to be able to randomly add props to fn objects
it’s this thing https://github.com/reagent-project/reagent/blob/86f622a9f94c6b559857e7a212e3cd34b9d16086/src/reagent/impl/component.cljs#L68
right, now i remember. it does this completely insane thing where it sets the function on a property of itself:
(if (reagent-class? f)
(cache-react-class f f)
(let [spec (meta f)
withrender (assoc spec :reagent-render f)
res (create-class withrender)]
(cache-react-class f res))
idk though, I’d have to dig through that whole path again to remember things enough. hah
Hello, I'm new to reagent and had a question about how it handles react template syntax {{key : "val"}}
can I just drop the outer {}
or is there some other syntactic sugar I should use?
Here is how to pass props to the components: https://github.com/reagent-project/reagent/blob/master/docs/UsingHiccupToDescribeHTML.md#using-hiccup-to-describe-html