TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Om Sweet Om: functional front-end engineering with ClojureScript and React

262 pointsby trevoragilbertalmost 11 years ago

9 comments

skrebbelalmost 11 years ago
Thanks for this post! I&#x27;m very inexperienced with Clojure, but I&#x27;m a big fan of React. I&#x27;ve always wanted to understand how Om encourages immutability and how it deals with &quot;UIs are stateful by definition&quot;, but I never managed to wrap my head around it, probably due to my missing Clojure skills.<p>Your post explained it in general terms. I will probably apply the same in plain JS now. It sounds like an interesting challenge to implement the Cursors idea using React&#x27;s Update addon [1] instead of depending on Mori. (I don&#x27;t like Mori because I don&#x27;t get the feeling that it&#x27;s intended to be used without ClojureScript - its API is rather cumbersome from plain JS)<p>[1] <a href="http://facebook.github.io/react/docs/update.html" rel="nofollow">http:&#x2F;&#x2F;facebook.github.io&#x2F;react&#x2F;docs&#x2F;update.html</a>
评论 #7906905 未加载
dustingetzalmost 11 years ago
fwiw it&#x27;s possible to achieve all of these benefits in vanilla react using javacsript with regular javascript data structures<p><pre><code> * single mutable ref to normalized app state * cursors for encapsulation and modularity * O(1) deep equality checks * fastest possible react performance </code></pre> source: I have done it in two large react apps, but i have not documented it yet. Blog post coming soon.<p>Interestingly, as your app state gets bigger, you are actually forced to use something like cursors for all state updates, for performance reasons. Naive immutability in javascript means clone-before-modify, which is far too slow when your state values are large. It quickly bubbled up in our profiler. Funneling all immutable updates through a cursor means the cursor can use structure sharing on the state value, skipping the defensive clone and preserving reference equality for equal subtrees. Also afaik, implementing a general shouldComponentUpdate (edit: in js) without something like cursors is not possible, because you need === equality for onChange props.
评论 #7906769 未加载
评论 #7906785 未加载
评论 #7906715 未加载
评论 #7906697 未加载
w01fealmost 11 years ago
Engineer @ Prismatic here. I&#x27;m happy to answer any questions about the post or our experiences with the rewrite.
评论 #7907186 未加载
评论 #7907512 未加载
评论 #7907542 未加载
评论 #7908149 未加载
评论 #7908886 未加载
评论 #7907334 未加载
jlehmanalmost 11 years ago
I&#x27;ve had the same experience building <a href="http://fitsmeapp.com" rel="nofollow">http:&#x2F;&#x2F;fitsmeapp.com</a> with Om&#x2F;Clojure -- great to see real, production apps being built in CLJS!
评论 #7906668 未加载
评论 #7906468 未加载
andrejewskialmost 11 years ago
For people who have wanted to try this type of programming out but have not jumped the boat from JavaScript to ClojureScript, I created a little library that mixes Backbone and React in a similar model described in the article: <a href="https://github.com/andrejewski/reactbone" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;andrejewski&#x2F;reactbone</a><p>It takes away a lot of the data-binding cruft that you find in Backbone.View and works well with React without making you switch languages, design paradigms, or add new libraries. The Backbone component makes it easier to build data hierarchies than with plain JS, but I assume other MVC frameworks could be retrofitted to work with React.
评论 #7907297 未加载
Touchealmost 11 years ago
It&#x27;s going to be much nicer when ClojureScript runs in Node without needing a JVM. Now a ClojureScript project requires a lot of boilerplate and running cljsbuild auto. For big projects this is fine but I want to write smaller scripts in ClojureScript as well. Basically I want to do:<p><pre><code> cljsbuild app.cljs &gt; app.js </code></pre> And that&#x27;s all. No project.clj, no waiting 5 seconds for clojure&#x2F;jvm to load and Closure to compile it all.
评论 #7908804 未加载
评论 #7906997 未加载
kylebrownalmost 11 years ago
I&#x27;m real curious about the potential interplay between core.async and om&#x2F;react. Bruce Hauman has a great tutorial on using core.async channels (as opposed to event callbacks) to process user input and gestures.[1] David Nolen (creator of Om) also covered core.async.[2] But these tutorials pre-date Om; core.async came to clojurescript in summer 2013, Om wasn&#x27;t released until 2014.<p>I guess the way React handles input is by attaching event handlers to child components, so that changes to the child properties bubble up to the root component state. Is this the optimal pattern for handling events in a React app? Or is there an advantage to be gained by using core.async channels to process event input for Om&#x2F;react?<p>I haven&#x27;t seen any examples which use both core.async <i>and</i> Om&#x2F;react, but I&#x27;m very curious about the possibility.<p>1. <a href="http://rigsomelight.com/2013/07/18/clojurescript-core-async-todos.html" rel="nofollow">http:&#x2F;&#x2F;rigsomelight.com&#x2F;2013&#x2F;07&#x2F;18&#x2F;clojurescript-core-async-...</a><p>2. <a href="http://swannodette.github.io/2013/07/12/communicating-sequential-processes/" rel="nofollow">http:&#x2F;&#x2F;swannodette.github.io&#x2F;2013&#x2F;07&#x2F;12&#x2F;communicating-sequen...</a>
评论 #7907250 未加载
评论 #7907305 未加载
评论 #7907213 未加载
habermanalmost 11 years ago
One thing that&#x27;s unclear to me: does this require the entire application state to be loaded into memory all the time?<p>If your application state is large but you only care about a few parts of it at a time (a few &quot;cursors&quot;) how does Om deal with that?
评论 #7907007 未加载
评论 #7906919 未加载
评论 #7907328 未加载
prestyalmost 11 years ago
I&#x27;m interested in knowing more about how people are architecturing their Om projects<p>e.g. are you using something like:<p>app component &lt;-&gt; page components &lt;-&gt; (widget) components<p>where the app creates the page and the page creates the widgets and communication is flowing through channels?<p>and how do you deal with url transitions?<p>do you capture and flow up the click from a widget back to the app so it knows it&#x27;s time to render a different page? and have some (case ...) at the app level?<p>or using some kind of mix with secretary and changing the location.href&#x2F;a hrefs?<p>etc
评论 #7907373 未加载