This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-08-31
Channels
- # aleph (38)
- # beginners (91)
- # boot (4)
- # cider (20)
- # clara (11)
- # cljs-dev (4)
- # clojure (179)
- # clojure-greece (1)
- # clojure-italy (16)
- # clojure-portugal (1)
- # clojure-russia (1)
- # clojure-sanfrancisco (1)
- # clojure-spec (183)
- # clojure-uk (50)
- # clojurescript (111)
- # core-async (24)
- # cursive (4)
- # datascript (11)
- # datomic (29)
- # fulcro (120)
- # gorilla (2)
- # jobs (1)
- # keechma (2)
- # keyboards (26)
- # leiningen (4)
- # luminus (7)
- # lumo (15)
- # off-topic (2)
- # onyx (31)
- # parinfer (12)
- # portkey (1)
- # protorepl (1)
- # re-frame (50)
- # reagent (106)
- # remote-jobs (1)
- # ring-swagger (2)
- # rum (10)
- # spacemacs (17)
- # sql (16)
- # test-check (1)
- # yada (2)
Quick sanity check. Since (not= #() #()) does that mean using inline functions as callbacks causes more re-rendering work than static functions?
the inline function should only get created once anyway
it's a good reason to not create functions inside eval, inside your component though
(as if we needed another one)
Thanks. What do you mean by "inside eval inside"
inside eval, inside your component
You mean inside render fn?
it would have to be inside the data your component reads in order to render, now that I think about it
Yeah, we're having trouble thinking our way out. You need the render context for most interesting inline callbacks
(without resorting to self/this )
right, anyway, in order for a function non-equality to make an extra render happen, you would have to do something convoluted and weird
unless of course the function was a replacible part of your render state, in which case I guess... you must have wanted that
We found a bug in https://github.com/PaulLeCam/react-leaflet where the prop change associated with an inline function update during render caused a full redraw which was heavy / slow.
That's not the typical case
I think react would simply update the onClick callback value which is not heavy
but still, interesting to note that it's extra work where a data value would not have changed
for re-frame you really want :on-click to accept a vector and dispatch
but that's a big change
And for amusement as much as anything else here's an example of how you could create a :on-click handler which dispatches but uses data equality...
(defn build-dispatch [& args]
(specify! #(dispatch args)
IDispatch
(-dispatch-args [_] args)
IEquiv
(-equiv [o other]
(if (implements? IDispatch other))
(= args (-dispatch-args other)))))
aaand it already exists but better in reagent.core ns !!!
(defn partial
"Works just like clojure.core/partial, but the result can be compared with ="
[f & args]
(util/make-partial-fn f args))
I have a TextInput
for currency and I'm formatting the value when it changes. Unfortunately, this causes a lot of flickering, since, when I input a number, it goes into the input, then the input refreshes with the new format.
; Using re-frame, the code looks something like this
[text-input {:keyboard-type :numeric
:placeholder (fmt/money 0)
:value (fmt/money amount)
:on-change-text #(dispatch-sync [::events/set-bet (fmt/parse-money %)])}]
that reminds me, is there a standard debounced input component or helper? (that's what I'd try to find or make for something like that but I have found other work arounds in the past)
I don't mind using create-class
and cooking something up, but I haven't found a single result when searching how to make a custom text input. i.e. something that spawns the keyboard, listens to key press events, and maintains the input state.
I'd basically want to make something just like TextInput
, except it doesn't append each char to the text value. Instead, it just calls a fn with each text change.
what if the edits were controlled by the user and not changed by the widget until they exit focus, with the resulting value previewed in a clickable dropdown?
kind of like the UI of autocorrect
that seems doable with a standard text widget plus some dropdown boilerplate
I've thought about something like that. Since the value would be updated on blur, for example, there would still be the issue of re-editing the now-formatted value. So I'd have to unformat it upon editing and format it after editing.
All of that seemed like as much work as should be required to do it a "better" way, but that may not be the case.
@jeaye that's on React Native, right?
I think the issue may be a reagent problem - DOM changes are made asynchornously, in the next tick
One thing you could try is (1) use a local state atom as the immediate backing buffer of the text-input, and (2) if that works sync it with re-frame.
Also you need to call (r/force-update this)
to short circuit reagent's event batching mechanism
@pesterhazy Yep, it's on React Native.
@pesterhazy Is there an example for that anywhere? Even accessing this
requires r/current-component
, right?
I ask because r/current-component
is always nil
in these callbacks, so I'm not quite sure how I'm meant to access this
.
right
here's how I do it
this is extracted and not tested in its current form, but it should help make the idea more concrete
why bind on-change in a let? Because that way, the prop doesn't change on each render, causing unnecessary rerenders.
I'm gonna give this a go and make any necessary tweaks. Thank you so much for illustrating this.
updated - I forgot to use !value
I wish slack didn't auto-expand gists
please check the Gist, not the preview
oh, and one problem is that this won't take into account changes of the value prop after it has been mounted - that may or may not be a problem depending on the use case
you could expand this to sync back prop changes but that makes things a bit more complicated
@pesterhazy If I add the formatting to that: https://gist.github.com/jeaye/291fc4f7f9cd4df7e3c27cccb8ab37e7
I still see a delay from when I hit a number and it shows up in the text box to when it's formatted properly.
so it first shows up unformatted, then formatted?
what if you don't update the value
prop at all - does it stay frozen or can you still type?
this mentions flickering
that'd be great
just tried this
(defn test-ui []
[n/text-input {:style {:margin-top 50
:margin-left 5
:background-color "#facade"}
:placeholder "bla"
:value "foo"}])
I see flickering even in this simple case
if you type, you see the char for a split second, then the change gets reverted
so this seems like a limitation of RN?
Recorded session, since I've already made it anyway. 😛 https://upload.jeaye.com/tmp/out.ogv
yeah that's janky as hell
I'd guess updating the value as you type is not a supported use case of TextInput
You could try raising an issue on github...
the docs mention something along those lines https://facebook.github.io/react-native/docs/direct-manipulation.html#setnativeprops-to-clear-textinput-value
(.setNativeProps @this' (clj->js {:text (format-value new-value)}))
Seems like the fn doesn't exist though; it's undefined.
you need to call it on the actualy text input
[text-input {:ref #(reset! !input %))]
with (let [!input (atom nil)] ...)
then (some-> @!input (.setNativeProps #js {:text "asdf"}))
yeah it's probably not possible currently
unless you write a native module
no problem
I've run into issues with TextInputs many times myself
I'm gonna compare the instant-text-input
to the normal text-input
, side by side, to see if there's a noticeable difference.
whats the function for converting hiccup into jsx so that it can be used by a plain react component
it's not JSX
JSX is just syntactic sugare for createElement
so as-element is right
another option is reactify-component
normally components don't take elements as props but functions that return elements, i.e. components
maybe you are working with a special case?