Fork me on GitHub
Ben Halton09:10:04

I'm using reagent in conjunction with MUI5. There is a well known issue with the cursor jumping to the end of the input when trying to edit in the middle of a text field. I've sorted that by following: This works for text fields but if I use :type "number"the jumping happens again.

Ben Halton09:10:21

I also see the following error

Ben Halton09:10:38

MUI: You have provided a `inputComponent` to the input component
that does not correctly handle the `ref` prop.
Make sure the `ref` prop is called with a HTMLInputElement. 

Ben Halton09:10:28

I also see some other slightly annoying things, like label shrink behaviour not working very well, although I think I can work around this

Ben Halton09:10:10

I'd really like to switch to controlled inputs in my app but I'm really struggling to get this behaviour 100%


That Reagent examples uses v4 while you're using v5, so that's where all the issues come from. One possible solution is to wrap the uncontrolled MUI input in a controlled component and have the external value supplied to MUI input be specified only when it truly changes externally and not via the MUI input itself. re-com adheres to this model:

Ben Halton10:10:09

thanks yeah I figured v5 might be the issue. I'll take a look at the example thanks. I feel like the issue with number inputs might have also affected us with v4 MUI but rolling back just now is a bit painful


If you're really curious and just want to test the number input on v4, you can just create a small test project - no need to roll back anything. But also, if you're using Git, rolling back while preserving all the changes in a separate branch is just a couple of commands. :)

Ben Halton10:10:10

yes - not so much the version of code that concerns me - I'm not very clued up with node/npm/shadow

Ben Halton10:10:36

so i'm concerned about dependency hell !


That's not really a concern - you just remove node_modules and run npm i again, that's it.

Ben Halton10:10:39


Ben Halton11:10:51

so I went back to have a look at v4 - it seemed to work well with numbers, and no console warning. I'd say with v5, using the old approach, text fields still work (but with console error) and number inputs are a bit odd - occasional jumping

Ben Halton11:10:29

at the risk of being thick - is there a way to make the inputComponent satisfy the warning ?

Ben Halton11:10:00

i.e. be an instance of HTMLInputElement?

Ben Halton11:10:40

I think short term I can make this kinda work by using text inputs and enforcing the number type another way - but obviously the error worries me a bit


No clue, I haven't switched from Material UI v4 myself.

Ben Halton11:10:42

sensible 🙂 I need to dig into reagent a little I think

Ben Halton13:10:58

well I spent a little time looking at this and didn't get far. This example

(def ^:private input-component
    (fn [props]
      [:input (-> props
                  (assoc :ref (:inputRef props))
                  (dissoc :inputRef))])))
doesn't seem valid now as props no longer seems to contain an :inputRef and tbh I'm not really sure what should go there


Have you tried the internal/external model approach yet?

Ben Halton14:10:08

not yet no - have been fiddling back and forth with v4 / v5 trying to spot the difference

Ben Halton14:10:35

will try to get a proper look over the weekend


I don't think that approach is worth the time - the differences can easily include implementation details and most likely include some API you will never use elsewhere. Whereas the internal/external model approach will work with any component, from any library. It's well worth learning it by itself.

Ben Halton14:10:05

yes I think I'm facing up to reality fairly quickly 🙂 I thought there might be magic incantation

Ben Halton07:10:46

so I had a look through the code and tried a few things myself - I could just be being thick but I don't see how that provides a fix for rerendering uncontrolled mui components? the problem with those is that re-rendering the component doesn't change the default-value, The only way I've found to force the re-render is to force a change in the key value of the component, this works but it feels a bit unwieldy.


Hold on. Your initial problem was caused by unneeded re-rendering. But now you actually do want to re-render? What gives?

Ben Halton07:10:43

I want to be able to control the value in the input externally

Ben Halton07:10:29

if I do this with a standard controlled input - I get cursor jumping

Ben Halton07:10:53

if I do it with a uncontrolled input - I don't get cursor jumping, but am unable to control the value in the input

Ben Halton07:10:00

unless I'm missing something fundamental ?

Ben Halton07:10:39

which is definitely possible - I"m really not much of a UI dev


Ah, right. The :key trick is an alright solution - I'd probably use it myself as well.

Ben Halton07:10:07

I nunderstood the old workaround of supplying a reagent input component to the MUI textfield - this meant reagent could apply cursor fixing

Ben Halton07:10:45

obviously I'd like to repeat that here but looking at the docs, its a bit beyond my react/js/reagent comprehension (if it's possible at all)

Ben Halton07:10:18

the section on integration with 3rd party input libs seems to be what we want

Ben Halton07:10:13

but how we supply a custom reagent managed input component that implements the right interface is a bit much for me


If :key works, why would you want to use something else?

Ben Halton07:10:38

anyway appreciate the help :thumbsup::skin-tone-2:

Ben Halton07:10:13

it seems more elegant to me - to use inbuilt fixes for a known issue - both react and reagent have their own fixes for cursor jumping

Ben Halton07:10:53

instead I need to implement a custom fix - I have done this elsewhere already but preferred the elegance of supplying a managed input


It's only elegant on the surface. :key + internal/external model will work for any kind of input, from any library. Whereas that solution of providing a custom component works only for that particular version of MUI, and nothing else.

Ben Halton07:10:18

that's a fair point

Ben Halton07:10:26

I have some abstractions I've built for forms and I guess I'll need to rework them to include a generic way to do "controlled" components at the momen the way I handle them is a bit ad hoc


Belatedly realized that I somewhat led you astray with that re-com link since re-com wraps controlled components. And an uncontrolled component needs a tad different approach. Sorry about that. But seems like you have figured that out already.


Just dug out some old code and found that I used (reagent.core/flush) in the :on-change handler there. I think it basically turns async rendering into a sync one, thus fixing the initial problem.

Ben Halton08:10:41

ah yes thanks - this is the path I was just heading down

Ben Halton08:10:34

was just seeing that react itself possibly does some sync update magic to work around the issue

Ben Halton08:10:00

I'm also looking at options of managing cursor position myself - this has some potential

Ben Halton09:10:52

I think I have come up with something based on managing cursor position myself ... seems to work at first glance so I'll get on and test this afternoon


I'm looking for some apps "made with clojurescript" (krell, reagent whatever). Reason is so my team mates can see for themselves if they can be made with quick startup / zappy