This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-05-09
Channels
- # aws (3)
- # beginners (61)
- # boot (1)
- # cider (80)
- # clara (5)
- # cljs-dev (5)
- # cljsrn (19)
- # clojure (40)
- # clojure-dev (29)
- # clojure-dusseldorf (2)
- # clojure-greece (21)
- # clojure-italy (16)
- # clojure-russia (7)
- # clojure-spec (31)
- # clojure-uk (70)
- # clojurescript (31)
- # cursive (21)
- # data-science (5)
- # emacs (7)
- # fulcro (23)
- # graphql (4)
- # java (18)
- # jobs (1)
- # jobs-discuss (25)
- # juxt (14)
- # nrepl (2)
- # off-topic (18)
- # om-next (2)
- # onyx (3)
- # re-frame (16)
- # reagent (50)
- # ring-swagger (5)
- # shadow-cljs (70)
- # specter (5)
- # sql (24)
- # tools-deps (16)
- # vim (41)
I made this complicated function which returns a react component using create-class
. I'm discovering that eg [inline-edit ...]
in a reagent form doesn't cause the component to re-render. What would be the preferred way of writing a complicated component like this eg switch to react's component local state or just invalidate the region where i'm rendering the component? (gist here: https://gist.github.com/doubleagent/3da6d623ab5b99bd1d4a4c1b3c43b7ed)
@doubleagent generally, the pattern of (defn my-comp [] (let [...] (r/create-class ...)))
works
i don’t think that pattern is the problem. there’s some other reason why it isn’t updating
what event is happening that causes you to believe that it should re-render but doesn’t
@lee.justin.m I'm rendering the component like this (defn page (let [...] [:div [:inline-edit ... (:number @ticket) ... (:desc @ticket) ...]]))
, where ticket is a ratom. I expected that when ticket changed value then the component would re-render. Every other component emitted from the page
function re-renders except this one, and one other component written in a similar style.
@doubleagent oh so you’re not repeating the arguments in reagent-render
so when the passed arguments change, the render func is just using the initial closed-over values
that seems to be the case
so just repeat the args from the outer function. then the render func will get the new values
Repeat the args from the outer function in the render fn? eg (r/create-class {:reagent-render (fn [<args>] ...)})
right, where args is some subset of {:keys [id placeholder validate submit-rec debounce-time working editable hover idle shared]}
just to paint a picture here: reagent will call inline-edit
the first time that its parent function is rendered. then it will save the result. on all subsequent re-renders, it will pass the same argument list to reagent-render
. because you don’t repeat the arguments in reagent-render
, those new values are not lexically visible to the render function
try this experiment: put a js/console.log
at the very top of inline-edit
and then another inside reagent-render
. i think it’ll make more sense then
I guess I'll have to move the existing (let [...])
block into the render function, and plug all the things previously defined in that block into an atom eg (defn inline-edit [<args>] (let [state (atom {})] (r/create-class {:reagent-render (fn [<args>] (let [<populate state atom>] ...)) ...})))
Does that sound right?
everything defined in the top-level let block is going to use the initial closed-over values
oh i see what you are saying. actually looking at my code, that’s what I do too, hah. i merge everything into an atom in the render func
you can actually emulate object state that way too. the functional programmer people would probably kill me if they saw this code but yea that works
lolol i'm finding that the reagent stuff only looks functional when it's simple
that's like 80% of my program so it's not a big deal 😉
use functional where it works and makes sense. but i’ve got one big component that is inherently mutative because it wraps a canvas, so I just emulate an object by passing a state atom around
honestly it’s no worse than every js component in react, so i figure do what’s natural
thanks man i'll give this a shot
it sounds simpler than I thought it would be
fwiw, my big component looked just like yours in that it was a big closure. i actually moved to the state atom thing because that was so annoying to deal with. now its just a bunch of little functions that take the state atom as an argument
that sounds nicer
its good because some parts don’t actually need the state atom or they only need a fraction of it--you can then just deref the atom and pass what you need, so you still get some partial decoupling and testability
Is there anything like this for reagent https://github.com/storybooks/storybook ?
@lee.justin.m I found repeating the args in the render fn required me to determine when and how to overwrite state on entry, so instead I moved all that stuff into compoonent-will-receive-props
and dumped everything into an atom like we talked about.
not tested yet but it compiles and renders the default state correctly
indentation is a mofo, lol
using smartparens
i mean there's too many indentation levels, lol