Fork me on GitHub
Raziyeh Mohajer06:07:50

Hello everyone I have a re-frame app and I want to receive input in my forms from the user. If I want to save the input in my re-frame db with each keystroke an event should be dispatched to change the db and it may lock the whole db to change that small field. Is it ok to store input in db or Should I make an atom to save the values that the user enters? What's the best practice for receiving input in re-frame?


hi @raziyehmohajer.rms, I use both ways you describe. Sometimes the performance is ok to use a dispatch, but sometimes it isn’t. What you could always do is this pattern: • store your value in a local atom, that is, an atom inside the component • use :on-blur to do the dispatch to the db • use :on-change to update the local atom #(reset! local-atom (-> % .-target .-value))

🤯 3
🎉 3

It kind of depends if a lot is subscribing to your change as well. If you save something to the db and not much is listening to that value, I suspect it will perform well to just do a direct dispatch and listen to the db’s value.

🤯 3
🎉 3

But if some complex subscription is re-computed on each keystroke, you might end up with sluggish UI.

Raziyeh Mohajer06:07:18

My problem is I want to check validity of the inputs before sending them to backend and also show the user if some other user changed that value and because of this I can't make a local atom in my component because other events should be able to change that local atom. But Also I think the logic on subscription is a little complex and I scare that it will cause, like you said, sluggish UI


ah so it’s like a multi-user concurrent editing form kind of thing?


to be honest, it’s all quite performant


I have some troubles when there’s a search/filter kind of logic (ie. combo-box where you search things), that re-renders large tables with complex cells, then it can become a bit sluggish


hard to tell from here if this will be problematic for your case


although; you could probably just try it, the ‘re-frame way’ that is. Shouldn’t be that hard to spike/try it maybe? Because it’s all nicely decoupled; your component can just shoot events, other users/things can shoot events, you don’t have to intertwine any code

Raziyeh Mohajer06:07:56

what do you mean by 're-frame way'?


Sorry, had a call. Well i mean using dispatch on each key-stroke, and not use a local atom.


well; that’s what I would do. To me it does seem that the re-frame way fits here… gut-feeling. Not per se because of the performance aspect, but because of the decoupling/architectural aspects

Raziyeh Mohajer06:07:30

@kah0ona I don't know what you mean by the re-frame way. Does re-frame have something special for this kind of situation?


I am not sure, whether this is a re-frame problem: When I include

[:link {:href "/bootstrap/css/bootstrap.min.css" :rel "stylesheet"}]
[:script {:src "/bootstrap/js/bootstrap.min.js" :type "text/javascript"}]
in my views, the bootstrap.min.js is never loaded, the .css is. Did I misconfigure something about re-frame or could this rather be a shadow-cljs problem?


IIRC adding <script> tags dynamically (or at least, with React) will not get them executed.


Regarding "whether this is a re-frame problem" - if you don't have subscribe or dispatch in your problem definition, then most likely it isn't.


Oh, the tags not being executed should be the problem. Is there any usefull pattern for doing it? (A little of topic). I would like to execute the js dynamically on some views only.


you need to interact with the DOM directly and add a script element


Thank you both :thumbsup:


a DOM diffing system like react is not ideal for this (as - for example - removing the script tag wouldn't remove the code you loaded)


i.e. the loaded java script is not actually part of the DOM


but I digress


Yeah, I am aware, that I am not asking for good practice advice here. 🙂 I probably will choose another solution.


Another question: Does anyone of you use something like devcards with re-frame? Does it function well?


@wegi the way to get around the single atom problem is to have your components get all the data through the props rather than subscribing within the functions.. I know some say that in a re-frame context each component should get its own data, but this approach doesn’t play nicely with devcards


Yeah, that is what I noticed as well. Additionally I would like to use a routing library like reitit, which also dispatches events, when certain views are entered. This complicates devcards use further


Yeah though I am using devcards to test individual small components.. I’m not rendering full views, as they add more complexity like in your example