Fork me on GitHub
#reagent
<
2024-01-09
>
Ivana10:01:42

I'm using the same component for both login & sign-in (register) puproses, and want to clear local state & reset (cleanup) the form only if input arguments were changed (not on local state change). My code below works, but isn't it a dirty hack? Or it's regular way to use the implicit side effects on component render?

(defn- register-login [register?]
  (r/with-let [state (r/atom nil)
               old-argv (atom register?)
               ref (atom nil)]
    ;; emulation of :component-did-update
    (do
      (when (and (not= register? @old-argv)
                 @ref)
        (reset! state nil)
        (.reset @ref))
      (reset! old-argv register?))
    [:form.main-header
     {:ref #(reset! ref %)
      :on-submit (fn [e]
                    ................

p-himik10:01:11

Sometimes you do have to use something like that. A cleaner approach would be to use a form-3 component and check that the only property has changed in :component-did-update. However, in your case I'd probably extract all the common parts into their own vars and use those to create separate form components - one for logging in and another for signing up.

1
Ivana10:01:56

Thanks alot, as usual! 🙂

Ivana10:01:56

Finished with 2 small components with different states while core is stateless form-1 component

(defn- register-page []
  (r/with-let [state (r/atom nil)]
    [register-login-core true state]))

(defn- login-page []
  (r/with-let [state (r/atom nil)]
    [register-login-core false state]))

p-himik10:01:37

Nice. FWIW, I usually suffix the names of such components with -impl instead of -core.

1
Ivana10:01:49

Ok. Btw, should I call that -impl as component or as regular function in round parens (register-login-core false state) ?

p-himik10:01:45

Doesn't matter that much when register-login-core doesn't have any state on its own.

👍 1
souenzzo16:01:35

Hello I'm working a big reagent app that uses r/with-let to manage the state. The issue was: a component was losing the state during a re-render. I managed to fix it my replacing a component call [my-wired-table ...] with a function call (my-wired-table ...) I'd like to know where can I read more about reagent implementation and the implications of [] vs (), or even the internals of r/with-let.

p-himik16:01:10

Usually it's the opposite - using () instead of [] can lead to a lost local state. [] creates a new component from the passed function, () just calls your function, that's it. I don't think r/with-let is documented to the fullest extent anywhere, so I'd suggest studying its implementation. If you can create an MRE, I'd be curious to take a look.

souenzzo16:01:06

> Usually it's the opposite Thank you. I used to understand things that way too. good to know that I'm not getting crazy > If you can create an MRE, I'd be curious to take a look. I'm trying to do that.