THIS PROJECT IS DEPRECATED
A new project has been created, observe-component that has an updated/more semantic API and will continue to be developed. The goal is to grow to become as library-agnostic as possible, to promote components-as-observables in all environments.
react-streamable
;;; const StreamableButton = ; { return <StreamableButton>Hello</StreamableButton>;} ; const clickStream = ;
API
streamComponent(Component, events[])
Returns a higher-order StreamableComponent
with an attached stream of the specified events. Supports all events supported by React's event system.
Example:
const StreamingDiv = ;
fromComponent(StreamableComponent, [ events[] ])
Returns the stream attached to the StreamableComponent
. An optional array of events
can be supplied to return a stream only containing those events.
Example:
const StreamingDiv = ; // will log all 'onMouseDown' and 'onMouseUp' events // will only log 'onMouseUp' events;
But why?
Because Functional Reactive Programming is pretty cool, and so is React. However, React's API is not very FRP-friendly; the necessity to wire up events by hand using buses (or subjects, in RxJS-speak) easily leads us to the Bus of Doom, and in general is finnicky and boilerplate-y to connect an observer to React.
There are also plenty of libraries for connecting streams to React, but very few (none that I've found) that transition React events to streams, enabling a fully functional reactive architecture.
Dependencies
At the moment, react-streamable
depends directly on Kefir for streams. There is no reason for this. The library could easibly be ported to RxJS/Bacon.js/Fairmont/whatever. Under the hood, it uses Kefir's pool
object (basically an equivalent to RxJS' Subject
, or Bacon's Bus
) to abstract the events into streams; we really never escape the bus, we just hide it. I'm interested in trying to create a portable version that can work with any reactive programming library.
More examples
A slightly more complex example
;;; const StreamableInput = ; { return <div> <div>Hello thispropsname!</div> <StreamableInput type="text" /> </div> ; } const nameStream = /* The streams values contain two properties: 'event': The name of the event that was triggered, e.g. 'onChange' 'e': The React SyntheticEvent */ ;
You can stream any component
...as long as you pass event handlers to the appropriate elements. The library simply passes special handlers to React's event system (on<Event>
) to abstract them into one stream.
{ return <div> <button onClick=propsonClick>Click me!</button> <input onChange=propsonChange defaultValue="Change me!" /> </div> ;} const StreamableWidget = ;const widgetStream = ;
However, you are strongly encouraged to create streams out of basic components and merge them, rather than manually pass the event handlers yourself.
; const StreamableButton = ;const StreamableInput = ; { return <div> <StreamableButton>Click me!</StreamableButton> <StreamableInput defaultValue="Change me!" /> </div> ;} const widgetStream = ;
License
MIT