Fork me on GitHub
#re-frame
<
2019-07-16
>
Ahmed Hassan19:07:59

What is best way to store input field values and show them in :value attribute of input in re-frame and reagent app ?

nenadalm20:07:24

In case you are typing into same :input you have :value @(subscribe [::field-value] on, some hits might even be missed (most noticeable with automated tests). You could either use :default-value instead of :value instead (that way initial values of the form will be correct, but no fields will be affected by any modifications to the app-db) or if you need to update :input values when db changes, you could use events :on-blur and :on-focus to store currently focused field for which you wouldn't add subscription for :value prop and have that subscription for all unfocused fields (so value for currently focused :input would sync once the input would lost it's focus). Example of :input with :default-value can be seen here: https://github.com/imatic/re-frame-form/blob/e4f2ca430dc83e3e9d78402c4dddee3a8ddb9480/examples/re-frame-form/src/example/core.cljs#L60 `

✔️ 4
Ahmed Hassan16:07:44

@nenadalm I'm using :default-value now, it works, but form is not cleared after submission.

Ahmed Hassan16:07:37

It only clears when for component re-renders.

Ahmed Hassan16:07:04

Is there any way to clear forms? or should I force re-render form component to clear it?

Ahmed Hassan16:07:24

@U08JKUHA9 I want to reset after confirmation that it's submitted to server.

nenadalm17:07:44

You could also reset the form by calling reset method on form element: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reset. You can get access to the element via :ref prop (https://reactjs.org/docs/refs-and-the-dom.html#creating-refs). It expects function that it will pass the element as first argument. Another option would be to do something like:

(defn form-component []
  (let [default-value ""
        
        ;; should we do the reset?
        reset @(re-frame/subscribe [:do-reset])
        
        ;; if we do reset, notify the app that the reset is done
        _ (when reset (re-frame/dispatch [:reset-done]))]
    
    [:input (merge {:type :email}
                   (when reset
                     ;; sets value of the input on reset
                     {:value default-value}))]))
instead of having the event and subscription for reset as above, you could also have correct values in app-db and pass :value prop in case the :input is not focused (then all your inputs would be synced with app-db in case they weren't currently focused, so you could reset the form by just setting correct values inside app-db).

4
Ahmed Hassan19:07:38

I'm storing values in re-frame db and showing them in :value attribute by subscribeing.

Ahmed Hassan19:07:04

But it is slowing down input reaction.

knubie19:07:56

It could be that your subscriptions are taking a long time

knubie19:07:02

for some reason

Ahmed Hassan19:07:59

I use one subscription for two input items.

Ahmed Hassan19:07:07

Subscription reads from same db entity in which it is written.

knubie19:07:48

you could try using re-frame-10x to debug where the latency is coming from: https://github.com/Day8/re-frame-10x

Lu20:07:50

If I may, I’d say don’t store the values in the global state.. for on-change events I’d keep it local with a ratom

Ahmed Hassan20:07:04

@UE35Y835W component appears and disappears on toggle button, but I want to persist state between toggles.

Lu20:07:23

I see! I’d store the values on-toggle with an event that takes your values from the ratom :) .. anyways I had the slowness problem once and it was due to a specific function that was being re-run over and over on every input change.. To see if this could be your case, writing in the inputs should get slower and slower as you keep typing.. (to notice go ahead and type about 100/200 chars in the input)

✔️ 4
Ahmed Hassan20:07:55

Or taking values from ratom on on-blur event and storing in app-db can work.

Ahmed Hassan20:07:41

storing values in app-db on on-change slows it more.

Ahmed Hassan16:07:04

Is there any way to clear forms? or should I force re-render form component to clear it?