re-frame and controlled inputs

509 views
Skip to first unread message

Shaun Mahood

unread,
Apr 2, 2015, 11:33:34 AM4/2/15
to clojur...@googlegroups.com
I've been working on my first app using re-frame and have run into the first real hurdle that I need some help with.

Basically, the re-frame pattern for dealing with text inputs as I understand it is as follows:
- Create the input as part of a component, and dispatch a handler as the :on-change method
- In the handler, update a field in the app-db
- Subscribe the component to changes on the input field so that it will stay in sync with the app-db

This is essentially the way it is dealt with in the simple-example provided with re-frame. Unfortunately, when the input field is edited anywhere but the end of the textbox, the subscription fires and sets the value causing the cursor position to be reset to the end of the textbox. See https://github.com/Day8/re-frame/issues/39 for more info.

I don't see this as being a major issue in reagent itself, but it causes problems with the mental model of re-frame. One of the real selling points of re-frame to me is the ability to just subscribe and re-render components without having to really worry about synchronizing renders, at least for basic elements. I ran into it specifically when loading fields to edit, where I would like to just subscribe the input value but will instead have to pass it in when calling the component initially. This means I'll lose the easy synchronization between the input value and the app-db, which kind of sucks.

I spent a couple hours yesterday trying to figure out how to get the cursor position to reset itself by adding it into my existing handlers, subs, and components with no real luck. I was able to get the cursor position to reset to the right position at the right time occasionally, but the majority of the time it would fire either too early or too late and end up in the wrong place.

Based on the re-frame wiki (https://github.com/Day8/re-frame/wiki/Creating-Reagent-Components), it looks like there might be a way to do this using form-3 components, but this seems like a lot of extra work to unload onto anyone developing using re-frame.

My ideal thought is that developers could follow the way things are done in the existing simple-example as closely as possible. I think that it would mean some changes to how re-frame works, either by wrapping any subscriptions to input fields (and textarea) and resetting the cursor position after the update is fired, or adding some sort of helper method to make it easier for developers to implement when needed.

I hope that was clear, let me know if there's anywhere I've missed anything obvious or where I need to elaborate on the problem.

Marc Fawzi

unread,
Apr 2, 2015, 11:55:11 AM4/2/15
to clojur...@googlegroups.com
I'm using raw Reagent with cursors and I don't have that problem. Input fields can be edited anywhere without the cursor jumping. React takes care of that I suppose.

One thought is that you maybe accidentally causing the component to re-instantiate on each state update. That's a common thing o do in Reagent by accident.


--
Note that posts from new members are moderated - please be patient with your first post.
---
You received this message because you are subscribed to the Google Groups "ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojurescrip...@googlegroups.com.
To post to this group, send email to clojur...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

Tim Gilbert

unread,
Apr 2, 2015, 11:57:07 AM4/2/15
to clojur...@googlegroups.com
Would it be possible to use :on-blur or a similar event in order not to update the app-db until the user's focus leaves the field? That might be a possible workaround, though it wouldn't work if you need character-by-character updates as the user types...

Tim
Reply all
Reply to author
Forward
0 new messages