

Baobab: A JavaScript data tree supporting Om-style cursors, with React mixins - lewisl9029
https://github.com/Yomguithereal/baobab

======
adrusi
There's already a fairly major software project (it's installed on a
significant portion of Linux desktops) called Baobab, part of the GNOME
desktop environment[1]. Not saying that software needs to have a unique name,
but "Baobab", a type of tree, is a pretty distinctive sounding name that
people would expect to be unique just because of how unorthodox it sounds. I
can imagine people getting confused.

[1]: [https://wiki.gnome.org/Apps/Baobab](https://wiki.gnome.org/Apps/Baobab)

~~~
riquito
I don't think that anyone may confuse a react javascript library with the
Gnome Disk Usage Analyzer. Yet, being the author of Baobab the PHP library
([http://www.sideralis.org/baobab/](http://www.sideralis.org/baobab/)), I
would have preferred a different name :-P

------
lux
After implementing Facebook's stock Flux (actions + constants + stores +
dispatchers + views), which quickly gets verbose, I saw this on r/reactjs the
other day and started playing with it and so far I've been impressed.

It takes some getting used to, but the mixins help reduce your code to actions
+ store + views and make it easier to reason about. There's a good post about
it, including simple server integration, here:

[https://www.codementor.io/reactjs/tutorial/flux-reactjs-
stat...](https://www.codementor.io/reactjs/tutorial/flux-reactjs-state-baobab-
library)

I was surprised at the lack of attention it got, but I hope that changes
because there are some good ideas here.

~~~
edvinbesic
I have only briefly checked out this library so take what I say with a grain
of salt, but from what it looks like we had a very similar implementation to
this on the project i'm currently involved with, also very inspired by Om.

At first it worked out great for us but as our application grew both in scope
and number of developers involved, we quickly ended up with a 'cursor soup'
where too many components were watching for changes individually.

It had a very negative impact on performance since components would
potentially re-render multiple times for a single change. In our last
implementation we ended up overcoming this by some fancy event consolidation,
but even so we had too many components 'touching' our tree.

We ended up reverting to a much simpler architecture and it has both made our
application dumber (which is great in terms of maintenance) but also more
performant. We currently have actions/stores/views where actions themselves
are dispatchers. By creating a few helper functions we overcome a large part
of the boilerplate but even without, it has proved worth it for us.

~~~
cnp
I've been thinking about cursors and the potential for this problem, too. In
your experience would you say that a strict flux pattern utilizing the
PureRenderMixin and immutable data is a better way to go, and that one should
avoid cursors completely for larger projects? It might be my lack of
understanding, but cursors bring me back to some of the more annoying aspects
of MVC, namely the potential for not knowing what is going on where.

~~~
edvinbesic
Obviously everything I say is anecdotal since I have no data to share but by
making components as dumb (i.e. PureRenderMixin) we reduced the amount of
logic within a component and were able to make it both faster and easier to
maintain. Maybe our approach was naive and Baobab fares better here.

Another important gain for us was re-usability of components. We have several
projects that use the same components that represent the same data but the
hierarchy of the internal state of the application can look quite different
from one another. Passing everything in as props and avoiding as much state as
possible has made this much easier as well.

I guess at the end of the day everything is a tradeoff one way or another and
you just have to pick yours, as cliche as that sounds. For us simplicity was
more important in this particular case.

------
egeozcan
I found Baobab to be really helpful by letting me focus on the application
logic, rather than implementing 1000 things to conform to a pattern. I'm not
saying that Flux is unnecessary, but I think it can be improved and this is a
nice direction, which conforms to the basic idea, if I get it right.

A blog post[1] from Christian Alfoni with some examples helped me get started
with it. The tree becomes a nice summary of your application which makes it
easier for someone new to your project to make sense of it. Also there's
another post about going isomorphic with it[2], which is intriguing.

[1]:
[http://christianalfoni.github.io/javascript/2015/02/06/plant...](http://christianalfoni.github.io/javascript/2015/02/06/plant-
a-baobab-tree-in-your-flux-application.html)

[2]:
[http://christianalfoni.github.io/javascript/2015/03/01/true-...](http://christianalfoni.github.io/javascript/2015/03/01/true-
isomorphic-apps-with-react-and-baobab.html)

------
smrtinsert
Watching ideas flow from the Clojure/Script community back into Javascript I'm
reminded of the positive impacts the Rails community had on Java web
development. I guess we're at that point in time with respect to Javascript.

------
DougBTX
Does anyone know of a library like this which plays nicely with TypeScript's
type checker? I've not come across a way to avoid the use of essentially un-
typed string keys in cursors like this.

~~~
jbrantly
See
[https://github.com/Microsoft/TypeScript/issues/394](https://github.com/Microsoft/TypeScript/issues/394)
and
[https://github.com/Microsoft/TypeScript/issues/1003](https://github.com/Microsoft/TypeScript/issues/1003)
for what the future may hold

------
bananaoomarang
Aha, I was looking for something along these lines yesterday. One of the nice
things so far about Flux so far though has been an absence of much unsettling
'magic' in the stack, which you get in Angular and Ember.

Will definitely check this out though, it seems sensible.

------
amccloud
Can someone compare and contract Baobab to immstruct?

~~~
dmnd
I'd be interested in reading about this too.

A superficial and perhaps temporary difference is "for performance and size
reasons baobab does not (yet?) use an immutable data structure", whereas
immstruct wraps immutable-js.

I'm curious if there are other differences though because at first glance they
seem to be separate implementations of similar ideas.

------
imaok
Can someone explain what problem this solves that just using flux can't? I'm
having trouble understanding how a tree structure is useful, because I can
imagine different actions affecting different stores in different orders. So I
wouldn't want changes to only bubble up, sometimes I would need them in the
other direction.

~~~
ericgj
I found David Nolen's talk at React conf useful in understanding the
motivation for cursors.
[https://www.youtube.com/watch?v=5hGHdETNteE](https://www.youtube.com/watch?v=5hGHdETNteE).
See in particular starting around 15:40. Cursors are used when you are strict
about global immutable state; whereas Flux (like React itself) is agnostic
about this. IMO this agnosticism means you end up with a more complex
architecture. David's point in the video is, even with cursors and immutable
state atoms, you end up with a parallel set of complications to deal with --
around questions of inter-component communication across nodes of the tree and
information hiding. He sketches Om's current solution to this using observable
cursors which kind of let you trace data-change dependencies between
components - but I have to say without understanding Om better it's a bit hard
to follow.

------
obvio171
So this is kind of a special-purpose Bacon.js stream processing library that
has one central Property that all events flow into and out of? I might not be
making any sense, this stuff is all new to me. Thanks for any clarification!

------
BenoitP
IMHO, JSON can be seen as the simplified, fat-free child, non Enterprise-
Edition of XML; where features are created out of popular demand -as opposed
to being created by committee decision-.

So far, we have:

XML -> JSON

BaseX, eXistdb -> MongoDB, RethinkDB

XSD, DTD -> JSON Schema

WSDL -> HATEOAS

XML-RPC -> JSON-RPC

XPath -> JSONPath

xmlns -> JSON-LD

SAX -> clarinet

\--------------------

Would we have:

XSLT -> Baobab ?

------
ericgj
Can someone explain the advantages of using this over mori (which doesn't
include cursors per se at the moment, but are easy to implement on top of mori
data structures)?

~~~
marbemac
Amongst other things, it's about 1/4 the size, and sticks to plain JS for
those not familiar with ClojureScript.

~~~
ericgj
Yah. I don't know ClojureScript but that doesn't stop me from using it. And
David Nolen pretty convincingly addressed the size question in "Javascript
Modularity Shaming"[1] - i.e.: use Google Closure Compiler.

[1]: [http://swannodette.github.io/2015/01/06/the-false-promise-
of...](http://swannodette.github.io/2015/01/06/the-false-promise-of-
javascript-microlibs)

------
fiatjaf
Impressive. I imagine it being useful in almost all my projects. But how fast
is it? Is using `shiftReferences` to enable pre-rendering comparisons a good
idea?

------
coldcode
I definitely want to try this when I get to building my client side web app,
this makes much more sense than the default flux idea with many stores.

------
dominotw
I am currently ' React.addons.update ' which i find very easy to use.

I am unclear what this lib brings to the table.

~~~
amccloud
Cursors allows child components without state to update the state of a parent
component.

------
thomasfl
Demo?

