jamesmacaulay / react-bacon

A little module for using React with Bacon.js
MIT License
118 stars 7 forks source link

Documentation #8

Open andreaferretti opened 10 years ago

andreaferretti commented 10 years ago

Are there any plans to document react-bacon? The fiddles may be enough for those familiar with bacon and react, but it would be nice to document how the two are meant to interact and be used together

kmcclosk commented 9 years ago

If you look in the spec folder you can see some examples of using the general event stream, however there are currently no test for the props/state streams, which I'm also curious about from a use standpoint.

andreaferretti commented 9 years ago

Uhm, still a little mysterious. I am familiar with React and not so much with Bacon, although I understand some of its basic blocks. What is not clear to me is how the two are meant to be integrated.

In React, one usually reacts to user events by changing the state of some component, which will in turn trigger a rerendering of parts of the view and so on. Bacon has a different model, where streams are a first class citizen, and more complex streams can be assembled from basic ones. Finally, some DOM manipulation routine is attached to a stream constructed this way.

What could be a useful way to merge the two points of view? For instance, one common issue while developing React application is the action at distance. That is, the interaction I am doing in a component should have effect on distant, unrelated components - say cancelling an item on a todo list should remove it from the calendar as well. A couple of patterns have emerged to deal with this, in particular Flux and Om.

Another example which would be complex to tackle in React is the case where there is a lot of two way data binding. Say, a complex form which is not statically defined, but derived dynamically from a schema definition. In this case, one cannot just attach each field to an item in the state, so keeping track of the binding manually in React becomes complex, especially so if the form requires nested components (because the state will live in a parent view).

Can Bacon do something to help in this kind of situations? For local propagation of state, I find the builtin React approach to be enough, but even then there may be examples of cases where Bacon can be of help too.

kmcclosk commented 9 years ago

For single page applications, I agree that you need to have what you described as action at a distance, since the nesting of the components a) might be dynamic or undeterministic b) should not determine dataflow. This is why AngularJS is largely a travesty (although there are workarounds). Not every application is based on nested components.

I don't use Flux, and don't necessarily like the implementation of it, but I do agree with it's concepts namely one-way data flow.

What I do is have one central datastore for the entire application. Every object in that datastore has a unique or unique derived identifier. These unique ids are passed to components. By passing in these id values, the component automatically subscribes to those objects via a mixin. To change the central datastore, components must use a API which enforces the structure of the datastore and which pushes out change events, which ultimately resolve to component setState calls.

react-bacon uses BaconJS but in my opinion it does things backwards. You have to imperatively plug a stream into a component in order to drive prop/state changes. Instead, subscribe should happen declaratively through props, IMHO.

kmcclosk commented 9 years ago

Also, you will probably really learn a lot from this: http://baconjs.blogspot.fi/2014/12/structuring-real-life-applications.html

jamesmacaulay commented 9 years ago

I think where react-bacon works best is with managing user input and other little async flows. It doesn't really help at all with sharing state between components. The GitHub user lookup fiddle is a good example of this:

Every use of Bacon is a little flow of data on a single component, typically from props to state. I played around with trying to share Bacon properties and event streams between components, but it gets messy quickly as components are mounted and unmounted, and in the end I didn't see much advantage passing streams around as opposed to passing handler functions around. Maybe there is a better way to go about it that I couldn't find.

jamesmacaulay commented 9 years ago

@kmcclosk:

react-bacon uses BaconJS but in my opinion it does things backwards. You have to imperatively plug a stream into a component in order to drive prop/state changes. Instead, subscribe should happen declaratively through props, IMHO.

Yeah, I would have preferred to have everything be entirely declarative, but I couldn't find a great way to do it, so I settled with this approach. I tried to make things as declarative as possible by at least having the propsProperty and stateProperty methods be memoized and idempotent.