Fork me on GitHub
#reagent
<
2018-07-18
>
valtteri05:07:52

In addition there’s that you get this if you happen to deref ratoms within the sequence: > Warning: Reactive deref not supported in lazy seq, it should be wrapped in doall: Which is not the issue with into.

valtteri05:07:57

As pointed out also in @pesterhazy’s blog post a few messages above. 👆

abdullahibra10:07:00

@pesterhazy thanks, that's good 🙂

abdullahibra10:07:29

i have another question guys

abdullahibra10:07:03

if is have reagent atom which is hash and have for loop which create input field and i want to save the changes to this field into reagent atom hash i have done this but i have a problem i got re-render the input field after one value digit

abdullahibra10:07:39

what i have :on-change #(swap! state assoc-in [:current (:name x)] (.. % -target -value)) and x is from for loop

pesterhazy10:07:01

that should work; I suspect the error is in the surrounding code @abdullahibra

abdullahibra10:07:46

actually they are two for loops

abdullahibra10:07:54

one outer and other inner

pesterhazy10:07:29

try to reduce it to a simple repro, it'll make finding the error easier (maybe you'll discover it yourself)

abdullahibra10:07:16

the actual situation i have is: i want to write multiple tables and each tables has multiple records and i want to collect input field values from each table and write to reagent atom hash

abdullahibra10:07:00

so i should have one for for tables and inner for for rows

abdullahibra10:07:28

and in the inner for i try to get input field values using the code above

pesterhazy12:07:55

typically you'll only use one atom, but it looks like that's what you're doing already

justinlee15:07:23

@valtteri yes that’s true in lazy seqs. but you can just insert a fully realized list, say.

justinlee15:07:23

i have this issue all the time where i need to map data structures into vectors. i do all kinds of goofy stuff with into and threading macros. the idea of splicing is intriguing and i wonder if you could get something similar by just adding another sequence type in reagent that realizes and splices rather than passing as an array type to react (and thus requiring keys)

justinlee15:07:08

but in the mean time i think the idea of just slapping a seq in there might be good enough if i can figure out a away of adding keys

roti15:07:43

I have following problem: I have a bunch of root components, which are equivalent to web pages and are rendered using a router. each such component has some parameters, but also has its own internal state (like uncontrolled react components). my problem is that inside the render function I somehow need to distinguish between rendering the because of internal state change, and rendering because the route and/or route params changed. think of such a component like a customer form, which receives the id as parameter and gets the rest of the data during initialization. I can can keep the parameters in a atom and detect when these change and trigger initialization, but somehow it feels dirty. do you have another solution for this problem?

justinlee15:07:07

i’m not quite sure i follow. sometimes a nice pattern in react is to layer components: the outer component does some work and depends on some things; it realizes the atoms and possibly causes side effects and then passes everything down as props to the inner component

justinlee15:07:48

so you might have an outer component that worries about the route and then passes the data as props to the inner component, which worries about the internal state

roti16:07:10

well, the issue is that the (inner) component has its own state (i.e. it does not depend only on the parameters). for example it receives an id, makes an ajax call, displays a loader while waiting for the response, and then does it's job. the issue here it has to figure out when to make an ajax call.

roti16:07:03

and doing that by detecting when the parameter is changed feels not right 🙂

justinlee16:07:39

i guess my suggestion is to factor the “loader” functionality out to its own component, then pass the data as a prop

justinlee16:07:01

i do something similar because i tend to make an ajax call on route change

roti16:07:14

so you mean the router should handle the ajax call? but the problem remains the same: when do you know to make the ajax call? just by detecting when the URL parameter has changed?

justinlee16:07:36

not in the router. i’ll have a form-2 component that takes the parameters off of the route, like, say, a document-id. it will load data as needed when it initializes its outer let and then passes that data as a prop to a subcomponent. this is also where i handle placeholders

roti16:07:05

what do you mean by placeholders?

justinlee16:07:20

[:div "Loading …"]

justinlee16:07:35

you may not need them. i need to load some data on route change before showing the component. it is nice to pull the “uninitialized state” logic out of the main component and into a higher level one

roti17:07:51

I don't think a form-2 component helps here very much. for example, when I paste into the browser address bar an URL which goes to the same component, but with different parameters, I don't think reagent creates another component instance, but rather just renders the existing one with different parameters. so in this case I still need to keep the old params around, check them, and if different load the data again

roti17:07:57

for example, old URL is: http://localhost#document/12, new URL (pasted into the address bar) is http://localhost#document/13

roti17:07:43

and I think this is not related to reagent in any way, the same issue occurs in React as well

roti17:07:17

my main question is whether there is a better or at least alternative solution to detecting parameter change in the render function

justinlee17:07:09

you’re right--i’m checking for a parameter change in the main render

justinlee17:07:13

i can’t think of how to deal with load-on-route change type behavior unless you go the re-frame route of naming all the state transitions and removing all of the async code from your components

juhoteperi17:07:55

@roti If you use the ID (12, 13) as React key (even outside a list) old component will be unmounted and new one created

wizard 4
justinlee17:07:29

whoa that’s a cool trick

juhoteperi17:07:25

I think key is commonly used like this with React to e.g. control transitions and reset forms using uncontrolled inputs (default-value)

justinlee17:07:37

i’m trying to decide if that’s awesome or evil 🙂

juhoteperi18:07:31

I thought I read about this in React docs but can't find a mention of this now

justinlee18:07:44

the main thing i don’t like about it is that it moves responsibility to the caller

justinlee18:07:50

i guess you could wrap (?)

juhoteperi18:07:35

> In order to reset the value when moving to a different item (as in our password manager scenario), we can use the special React attribute called key. When a key changes, React will create a new component instance rather than update the current one. Keys are usually used for dynamic lists but are also useful here. In our case, we could use the user ID to recreate the email input any time a new user is selected:

juhoteperi18:07:48

Also here: https://reactjs.org/docs/react-component.html#constructor > You can ... force a component to “reset” its internal state by changing its key when necessary.

kennytilton18:07:11

I find it significant that after the VDOM hack failed to scale on collections the “key” solution turned out to be a problem itself. For those of you new to the field, this is how we identify failed engineering. (Mistake on mistake.)

kennytilton18:07:56

Kudos to the React team for declarative/functional views, but go back and fix the VDOM attempt to make them performant. There are other ways.

juhoteperi18:07:56

Uh, what? What's the problem with keys?

justinlee18:07:58

one person’s “hack” is another person’s “heuristic”

kennytilton18:07:00

(1) Now I need keys when a radio group has three items. I was going to say two but that could be a checkbox. 🙂

kennytilton18:07:25

(2) Now I need to come up with a key.

kennytilton18:07:33

(3) The need to optimize a list comes up very rarely (now see #2)

juhoteperi18:07:36

I disagree about 3.

kennytilton18:07:32

@lee.justin.m The ugly head of moral relativism raises its head! 🙂

juhoteperi18:07:46

It is quite common to render tables/lists with few hundred (or even thousands) items, keys matter.

justinlee18:07:16

(1) you only need keys unless you’re passing a sequence (which will get passed as an array when it gets down to react). just create the hiccup you need and you can avoid it if it bothers you. (2) you can always just pass the index if you know the performance optimization doesn’t apply

juhoteperi18:07:21

But for small static lists you can easily render them without keys.

juhoteperi18:07:42

Anyway, this isn't even due to vdom/React, if you manipulate DOM directly or something you need to eventually have identity for sequence items to efficiently updated them.

justinlee18:07:44

also you said there are other ways to do this--it would be interesting to know what they are. generalized tree diffing is n^3. using the react heuristic it is linear. the key trick is to get back some performance on big lists. it’s a compromise based in pragmatism

kennytilton18:07:03

@juhoteperi That’s OK, the frequency is a minor issue. I just hate putting keys on a fixed radio group.

juhoteperi18:07:19

What do you mean with fixed radio group?

justinlee18:07:22

@hiskennyness then don’t do that. use into

juhoteperi18:07:49

(for [i (range 5)] [:input {:type "radio" ...}])? Yes, use into

kennytilton19:07:08

@juhoteperi You mean the “into [:div]…” trick. The fact is, I coded a tiny radio group without keys and got barked at.

juhoteperi19:07:31

It is not "trick"

juhoteperi19:07:12

The resulting Hiccup is exactly the same as if you'd write div with 5 inputs directly, React will see exactly same elements

kennytilton19:07:35

OK, that just makes my point. I was coding naturally and got barked at. Now I need a (simple!) code trick. That is my point. That would not be necessary if they had done this right.

justinlee19:07:10

again I wonder, how should they have done it “right”

kennytilton19:07:14

“The resulting Hiccup..” Sure, and the resulting Java bit codes… 🙂

kennytilton19:07:59

(1) No whining on un-keyed lists

kennytilton19:07:53

(2) Just make it a frickin FAQ!

justinlee19:07:08

(side point: if you got a key warning then you constructed a data structure with a sequence in it. the point of using into is to splice a sequence into the vector)

justinlee19:07:29

so you think react sucks because it provides a warning? lol. just ignore the warning!

kennytilton19:07:26

@lee.justin.m Please do not speak for me unless you are inside my head, and lawdy, you do not want to be there.

justinlee19:07:00

when did i speak for you? you’ve spoken for yourself. you’ve called the vdom a “mistake” and the key optimization a “hack”

justinlee19:07:16

you’re only suggestion so far is to remove the warning

justinlee19:07:08

let’s see you also called it “failed engineering” and “Mistake on mistake”

kennytilton19:07:32

React did give the world a gift by turning us all on to declarative/functional programming. Then they stumbled on the importance of state management. This is actually a very interesting story in itself, since they have now explicitly rejected reactive state management.

kennytilton19:07:24

“So you think react sucks because…” Now I have words in my mouth I need to convince the world of otherwise. That’s OK. I really was kidding with you on that. But it does make it easier if you avoid the wife beating questions.

kennytilton19:07:20

Yes, they came up with a great functional approach to UI and then said explicitly that they were leaving state to us, as if it were a gift. They simply did not understand what Fred Brooks brilliantly identified in “No Silver Bullet”: the problem is interdependency of state.

kennytilton19:07:08

Had they solved the problem with point granular reactivity, they would not have first incurred the cost of generating all vdom all the time, then the cost of diffing. When that failed to scale they did not backtrack, they soldiered on with “heyDontUpdateMe” and keys on lists. Mistake on mistake.

justinlee19:07:54

i have no idea what “point granular reactivity” is, but react definitely scales 🙂 some of the biggest and most complicated websites in the world run on it

kennytilton19:07:26

Sure, and look at StoneHenge! Folks can do astonishing things with whatever is at hand, so our analysis of whatever is at hand cannot rely on outcomes. You would not believe what I have done with Cobol. 🙂

kennytilton19:07:14

“point granular reactivity” means “this property of this thing is a function of these properties/things”, vs “when any of my state changes re-render my entire component and any sub-components”

kennytilton19:07:15

“Sub-components” is prolly the wrong word for nested DOM open-coded in a component”

milomord21:07:56

Have you ever found the presence/use of the VDOM to be a performance bottleneck in real world usage?

milomord21:07:31

Or is it more about the developer ergonomics of what working with it necessitates (e.g. keys as above)

milomord21:07:24

I guess my general pain point tends to be related to having to work with browser standard APIs at some stage in a cross-browser/reasonable way, which I think reagent/React/Clojure does a good job of hiding from me most of the time, but this is probably because of the sorts of applications I have to build more than anything else

kennytilton21:07:20

Yes, @milolord, but not in apps at the scale of TodoMVC. My experience indeed was starting with functional expression of a dense UI (to sort out screen geometry, something browsers handle for us today), which was too slow as we scaled from proof-of-concept back to the dense UI, so we first did cacheing and then necessarily intelligent cache invalidation supported by point deoendency tracking. Without ever intending to, we were doing dataflow/reactive programming. It was rather exhilirating, as folks discovered when they found ReactJS declarative views.

kennytilton22:07:31

I think Facebook has put a lot of good engineering behind ReactJS, which might be one reason to build atop it. But then I look at their audacity in breaking the semantics of onchange to suit their philosophy of state (like they are the experts on state) and I do not think I want to be hitched to that wagon. I am hoping google closure will do well on cross-browser, or something like qooxdoo.web, the core.

kennytilton22:07:00

Final note: VDOM is not the real problem with ReactJS, it is just the first artifact of their weak approach to the problem of state in UI apps. They have now gone all in and explicitly rejected the reactive module (and, yes, they see the irony in their chosen name).