React + ClojureScript

Showing 1-10 of 10 messages
React + ClojureScript Alexander Solovyov 10/1/13 1:33 PM
Hi all,

last weekend I and my friends participated in Clojure Cup and because of that a small library was written, making React much more pleasant to use in ClojureScript: https://github.com/piranha/pump

There are a couple of deficiencies I wanted to solve, starting with CLJS data structures inside of props and state. If you don't know, CLJS has highly efficient immutable data structures, and they are totally incompatible with regular arrays and objects (by incompatible I mean that they don't support assigning with '=' operator), and initially we've planned to use them as state and props on components. 

It turned out to be working quite well with props once you get past root component (see later), except for "ref" not working since React couldn't take it from props and "children" not working since even when React sets it, I cannot access it by using CLJS means and have to drop to JS accessors.

It does work less good with state, since React on setState makes a shallow copy of state, which means dropping prototype - and that destroys CLJS data structures. So what we did is putting all state in state.state property and use few functions/wrappers to make it transparent. The same problem happens with (mentioned earlier) root component props, we do root.setProps({props: data}) right now, and then in component just take them out as first operation.

So my question is if we can somehow integrate better. Maybe writing a plugin with a new strategy for setstate/setprops/etc is viable? I don't know much about internals of React but I'm willing to dive to improve integration.

Another thing is that CLJS uses Google Closure and Closure Compiler extensively, and supports Closure Compiler advanced mode (which compresses really impressively!), and I would love to integrate React there to get even more compression - right now I have to tell Closure Compiler to treat react as external component using this extern [1] (thanks Daniel!), which means longer code where I interface react plus not destroying unused code in React.

But I don't know much about Closure stuff unfortunately. If somebody does please help, I would really appreciate that!

And thanks all of you guys for creating React, it is amazing piece of work.

P.S. If you by any means are at least a bit interested in ClojureScript, give it (and pump) a go! It was a blast using it in a real project, and I liked it so much that I'm now thinking how can I sneak it in my current work project...


Re: React + ClojureScript Pete Hunt 10/1/13 1:42 PM
This sounds sweet! Will have to digest it a bit further :)

If you used Clojure objects for props and state does that mean there'd be no GCs within your render() methods?

One thing to note is that we are pretty close to Closure Compiler Advanced Mode compatible. It should only be a couple of tweaks to get it working (i.e. we use keyOf() everywhere). Feel free to open an issue for this or take a stab at it.

Pete
Re: React + ClojureScript Alexander Solovyov 10/1/13 1:47 PM
On Tue, Oct 1, 2013 at 11:42 PM, Pete Hunt <floyd...@gmail.com> wrote:
This sounds sweet! Will have to digest it a bit further :)

If you used Clojure objects for props and state does that mean there'd be no GCs within your render() methods?

Hmm... I think it should be so... I'm not really sure, to be honest, I'm not an expert in CLJS implementation, but I can redirect your question. I guess it's important to keep render perfomant, right?
Re: React + ClojureScript Alexander Solovyov 10/1/13 1:58 PM
There is another issue which I forgot to write about, which is about how setState works: it puts all modifications into a queue and then executes them one by one in a single go. Which in JS is ok, if you did setState({x: 1}); setState({y: 1}), you'll end up with {x: 1, y: 1}.

But in CLJS I do (.setState this (js-obj "state" (assoc state :key "value"))) (sorry about writing a bit too much code, but it makes issue more clear), and if I do that few times in a row, state I get from React is the old one before all my calls (because they are waiting to be executed). And when they are executed, only one of them (last one I guess) is getting in, since I obviously just replace state with new one.

This means I have to be careful when doing state updates. :-) I would love to solve this problem as well... Not sure how though, but if we will get somehow to the point we can teach React about CLJS data structures, that'll make everything easier, of course.
Re: React + ClojureScript Pete Hunt 10/1/13 2:15 PM
Per our discussion in IRC, just build your own version of setState() that just calls replaceState() (or just use replaceState() directly).
Re: React + ClojureScript Dustin Getz 10/1/13 5:33 PM
Alexander, will you be at Clojure Conj in november? I'd love to talk about react + cljs and would be interesting in forking react to use CLJS datastructures. 

> except for "ref" not working 

In my codebase (enterprisey apps that look like this) I haven't found a single place where using refs were a good idea and kind of think they should be removed from react. In my experience we are always better off by using value/onChange props rather than maintaining state at the "bottom" of the views and getting at it with refs.

Can't wait to get my hands on Pump...
Re: React + ClojureScript Pete Hunt 10/1/13 7:30 PM
Dustin in general I agree with you that refs should be used rarely. However they are useful for two things I've noticed: DOM measurement and (more importantly) sending an "impulse" down the tree. Imagine that you want to show an animation as the result of an event in the system (like a click) rather than an actual state transition. Sometimes they're most naturally reflected as method calls on refs.

Also before forking React to support cljs please talk to us :) After working through this a bit on IRC I think we can probably make React flexible enough to work without a fork.

Pete
Re: React + ClojureScript Vyacheslav Slinko 10/1/13 9:12 PM
Don't agree :) I'm using refs in half of my components. :)
Re: React + ClojureScript Alexander Solovyov 10/2/13 1:58 AM
On Wed, Oct 2, 2013 at 3:33 AM, Dustin Getz <dusti...@gmail.com> wrote:
Alexander, will you be at Clojure Conj in november? I'd love to talk about react + cljs and would be interesting in forking react to use CLJS datastructures. 

I will not unfortunately. :( It's too far away and will cost a lot of money to get there, but I'm really willing to attend one of clojure conferences. :)
Re: React + ClojureScript Conrad Barski 10/27/13 5:19 PM
Hi Alexander, I was running into the same issues as you with the state, very helpful to read your comments. I will be sure to post any caveats I've found beyond the ones you've listed (none yet)