- Notifications
You must be signed in to change notification settings - Fork44
acdlite/redux-rx
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
RxJS utilities for Redux. Includes
- A utility to create Connector-like smart components using RxJS sequences.
- A special version of
bindActionCreators()
that works with sequences.
- A special version of
- AnFSA-compliant observablemiddleware
- A utility to create a sequence of states from a Redux store.
npminstall--saveredux-rxrx
import{createConnector}from'redux-rx/react';import{bindActionCreators,observableMiddleware,observableFromStore}from'redux-rx';
This lets you create Connector-like smart components using RxJS sequences.selectState()
accepts three sequences as parameters
props$
- A sequence of props passed from the ownerstate$
- A sequence of state from the Redux storedispatch$
- A sequence representing thedispatch()
method. In real-world usage, this sequence only has a single value, but it's provided as a sequence for correctness.
selectState()
should return a sequence of props that can be passed to the child. This provides a great integration point forsideways data-loading.
Here's a simple example using web sockets:
constTodoConnector=createConnector((props$,state$,dispatch$)=>{// Special version of bindActionCreators that works with sequences; see belowconstactionCreators$=bindActionCreators(actionCreators,dispatch$);constselectedState$=state$.map(s=>s.messages);// Connect to a websocket using rx-domconst$ws=fromWebSocket('ws://chat.foobar.org').map(e=>e.data).withLatestFrom(actionCreators$,(message,ac)=>()=>ac.receiveMessage(message)).do(dispatchAction=>dispatchAction());// Dispatch action for new messagesreturncombineLatest(props$,selectedState$,actionCreators$,$ws,(props,selectedState,actionCreators)=>({ ...props, ...selectedState, ...actionCreators}));});
Pretty simple, right? Notice how there are no event handlers to clean up, nocomponentWillReceiveProps()
, nosetState
. Everything is just a sequence.
If you're new to RxJS, this may look confusing at first, but — like React — if you give it a try you may be surprised by how simple andfun reactive programming can be.
TODO: React Router example. Seethis comment for now.
render()
is an optional second parameter which maps child props to a React element (vdom). This parameter can also be a React Component class — or, if you omit it entirely, a higher-order component is returned. SeecreateRxComponent()
ofreact-rx-component for more details. (This function is a wrapper around that library'screateRxComponent()
.)
Not that unlike Redux's built-in Connector, the resulting component does not have aselect
prop. It is superseded by theselectState
function described above. Internally,shouldComponentUpdate()
is still used for performance.
NOTEcreateConnector()
is a wrapper aroundreact-rx-component. Check out that project for more information on how to use RxJS to construct smart components.
This is the same, exceptdispatch$
can be either a dispatch functionor a sequence of dispatch functions. See previous section for context.
The middleware works on RxJS observables, and Flux Standard Actions whose payloads are observables.
The default export is a middleware function. If it receives a promise, it will dispatch the resolved value of the promise. It will not dispatch anything if the promise rejects.
If it receives an Flux Standard Action whosepayload
is an observable, it will
- dispatch a new FSA for each value in the sequence.
- dispatch an FSA on error.
The middleware does not subscribe to the passed observable. Rather, it returns the observable to the caller, which is responsible for creating a subscription. Dispatches occur as a side effect (implemented usingdoOnNext()
anddoOnError()
).
// fromEvent() used just for illustration. More likely, if you're using React,// you should use something rx-react's FuncSubject// https://github.com/fdecampredon/rx-react#funcsubjectconstbuttonClickStream=Observable.fromEvent(button,'click');// Stream of new todos, with debouncingconstnewTodoStream=buttonClickStream.debounce(100).map(getTodoTextFromInput);// Dispatch new todos whenever they're createddispatch(newTodoStream).subscribe();
Creates an observable sequence of states from a Redux store.
This is a great way to react to state changes outside of the React render cycle. Seethis discussion for an example. I'll update with a proper example once React Router 1.0 is released.
Also, I'm not a Cycle.js user, but I imagine this is useful for integrating Redux with that library.