RxJS utilities for Redux.

Related tags

Redux Tools redux-rx
Overview

redux-rx

build status npm version

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.
  • An FSA-compliant observable middleware
  • A utility to create a sequence of states from a Redux store.
npm install --save redux-rx rx

Usage

import { createConnector } from 'redux-rx/react';
import { bindActionCreators, observableMiddleware, observableFromStore } from 'redux-rx';

createConnector(selectState, ?render)

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 owner
  • state$ - A sequence of state from the Redux store
  • dispatch$ - A sequence representing the dispatch() 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 for sideways data-loading.

Here's a simple example using web sockets:

const TodoConnector = createConnector((props$, state$, dispatch$) => {
  // Special version of bindActionCreators that works with sequences; see below
  const actionCreators$ = bindActionCreators(actionCreators, dispatch$);
  const selectedState$ = state$.map(s => s.messages);

  // Connect to a websocket using rx-dom
  const $ws = fromWebSocket('ws://chat.foobar.org').map(e => e.data)
    .withLatestFrom(actionCreators$, (message, ac) =>
      () => ac.receiveMessage(message)
    )
    .do(dispatchAction => dispatchAction()); // Dispatch action for new messages

  return combineLatest(
    props$, selectedState$, actionCreators$, $ws,
    (props, selectedState, actionCreators) => ({
      ...props,
      ...selectedState,
      ...actionCreators
    }));
});

Pretty simple, right? Notice how there are no event handlers to clean up, no componentWillReceiveProps(), no setState. 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 and fun reactive programming can be.

TODO: React Router example. See this 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. See createRxComponent() of react-rx-component for more details. (This function is a wrapper around that library's createRxComponent().)

Not that unlike Redux's built-in Connector, the resulting component does not have a select prop. It is superseded by the selectState function described above. Internally, shouldComponentUpdate() is still used for performance.

NOTE createConnector() is a wrapper around react-rx-component. Check out that project for more information on how to use RxJS to construct smart components.

bindActionCreators(actionCreators, dispatch$)

This is the same, except dispatch$ can be either a dispatch function or a sequence of dispatch functions. See previous section for context.

observableMiddleware

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 whose payload 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 using doOnNext() and doOnError()).

Example

// 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#funcsubject
const buttonClickStream = Observable.fromEvent(button, 'click');

// Stream of new todos, with debouncing
const newTodoStream = buttonClickStream
  .debounce(100)
  .map(getTodoTextFromInput);

// Dispatch new todos whenever they're created
dispatch(newTodoStream).subscribe();

observableFromStore(store)

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. See this 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.

Comments
  • Allow more maintainers

    Allow more maintainers

    @acdlite

    I greatly appreciate what you've done to get this started and I'm sure it came out of a passion for using RxJs with Redux/React for yourself. However, there are several simple clean up tasks that are going by the wayside due to how busy you are and it's preventing those interested from adopting a truly Reactive application from using your great and simple library.

    My one request is that you open this up to maintenance by more people so that the following items can get done:

    • [ ] Publish the latest version with the fix for the Redux Middleware API to NPM
      • somehow npm install redux-rx installs version 0.5.0 but the latest Release for the repo is tagged as 0.4.0, neither of which have the fix for the Middleware API
    • [ ] close several issues which have been resolved
    • [ ] Improve the examples that are provided by including import statements at the top and an example of how to use it with react-redux, specifically:
      • [ ] finish the createConnector example by showing how it is used with the Todo component
      • [ ] personally an example of passing props down from parent containers to child components, e.g. what does the binding statement look like?
    • [ ] Provide examples of the other parts of the API, e.g. the current example for observableMiddleware doesn't even include observableMiddleware in the example
    • [ ] Make rx and redux peer dependencies
    • [ ] Update react-component-rx dependency => rx-recompose
      • OR should we be using that completely instead of this package?
    • [ ] Document what other packages are necessary ( rx-react ?) or useful ( recompose - another one of yours ) in order to understand the examples or make it easier to use this library
    • [ ] Have an ability not to use FSA compliant actions - this appears to be an arbitrary dependency but I could be wrong

    Personally, I'd be more than happy to perform these activities but at the moment I'm struggling with learning how to use this with my own new implementation of React+Redux Universal so I certainly can't provide help with examples

    Thanks again!

    opened by eudaimos 14
  • Show rx is as a dependency in the README

    Show rx is as a dependency in the README

    As I said wrote in https://github.com/acdlite/react-rx-component/pull/9, redux-rx will fail without rx installed because react-rx-component depends on it.

    opened by cesarandreu 1
  • Any plans for creating typescript definitions? Also, is rxjs5 on the roadmap?

    Any plans for creating typescript definitions? Also, is rxjs5 on the roadmap?

    Are there any types available for redux-rx? I tried npm install @types/redux-rx and looks like there are none. Eventually I tried the following:

    tsconfig.json

    "typeRoots": [
        "./node_modules/@types",
        "./public/shared/types"
    ]
    

    index.d.ts

    declare module 'redux-rx';
    

    Eventually i got this error. After some digging on the web I understand that rx is v4 and rxjs is v5

    ERROR in ./node_modules/redux-rx/lib/observableFromStore.js
    Module not found: Error: Can't resolve 'rx' in '....\node_modules\redux-rx\lib'
     @ ./node_modules/redux-rx/lib/observableFromStore.js 6:10-23
     @ ./node_modules/redux-rx/lib/index.js
     @ ./public/main.ts
     @ multi (webpack)-dev-server/client?http://localhost:8081 ./public/main.ts
    

    Considering that all I need is the following, I'll just write it myself in a service.

    function observableFromStore(store) {
      return _rx.Observable.create(function (observer) {
        return store.subscribe(function () {
          return observer.onNext(store.getState());
        });
      });
    }
    

    Updated

    function observableFromStore(store: Store<AppState>) {
        return Observable.create((observer: any) => {
            return store.subscribe(() => {
                return observer.next(store.getState());
            });
        });
    }
    
    opened by adrian-moisa 0
  • deprecated and unused dependencies?

    deprecated and unused dependencies?

    using react-rx-component which is deprecated?

    also requires react-redux which is not used except during tests, so it should be moved to devdependencies?

    opened by acornejo 0
  • Roadmap for Future Development

    Roadmap for Future Development

    From a comment by @chicoxyzzy in #18 - a chance for those actively using this library to weigh in on what gets done next.

    My thoughts are (reprinted/modified from #18):

    • [ ] Publish the latest version with the fix for the Redux Middleware API to NPM
      • somehow npm install redux-rx installs version 0.5.0 but the latest Release for the repo is tagged as 0.4.0, neither of which have the fix for the Middleware API
    • [ ] close several issues which have been resolved
    • [ ] Improve the examples that are provided by including import statements at the top and an example of how to use it with react-redux, specifically:
      • [ ] finish the createConnector example by showing how it is used with the Todo component
      • [ ] personally an example of passing props down from parent containers to child components, e.g. what does the binding statement look like?
    • [ ] Provide examples of the other parts of the API, e.g. the current example for observableMiddleware doesn't even include observableMiddleware in the example
    • [ ] Make rx and redux peer dependencies
    • [ ] Update react-component-rx dependency => rx-recompose
      • OR should we be using that completely instead of this package?
    • [ ] Document what other packages are necessary ( rx-react ?) or useful ( recompose - another one of yours ) in order to understand the examples or make it easier to use this library
    • [ ] Have an ability not to use FSA compliant actions - this appears to be an arbitrary dependency but I could be wrong

    Not necessarily in that order.

    Also some comments from @acdlite in that issue thread that modify the list above:

    In addition to the sensible steps you've listed like pushing the changes to the middleware API, my suggestion is that createConnector() should be removed in favor of using rx-recompose (or similar) directly. That project + observableFromStore() + .flatMap() gives you all the power you need, and would allow the library to be view framework agnostic.

    In response to my example which is

    import Redux from 'redux';
    import { Observable } from 'rx';
    import { observableFromStore } from 'redux-rx';
    import { observeProps } from 'rx-recompose';
    
    const storeState$ = observableFromStore(store);
    const fooState$ = storeState$.map(state => state.fooKey).distinctUntilChanged(fstate => fstate.id);
    const FooCtor = observeProps(props$ => {
        return Observable.combineLatest(props$, fooState$, (props, fooState) => Object.assign(props, fooState);
    });
    
    const Foo = FooCtor(<div>…</div>);
    
    • I'm not sure where to use .flatMap(…) above and could use some assistance on that
    • I'm not sure if I'm implementing it right using Object.assign(…)

    he also wrote

    Yeah, if you do it like that you don't need .flatMap(). I was thinking about a situation like this, where you grab the store from the stream of props:

    const enhance = compose(
      getContext({ store: PropTypes.object }),
      observeProps(props$ => {
        const storeState$ = props$.flatMap(props => observableFromStore(props.store))
        // ...
      })
    )
    

    observableFromStore() already supports disposal because the function passed to Observable.create() returns an unsubscribe function. Admittedly, this isn't exactly clear from the source, but here's the longer version:

    export default function observableFromStore(store) {
      return Observable.create(observer => {
        const unsubscribe = store.subscribe(() => observer.onNext(store.getState()));
        // By returning unsubscribe, the observable can be disposed
        return unsubscribe;
      });
    }
    

    Is there anything else you'd like to see? What's immediately needed for your project? What do you want longer term?

    opened by eudaimos 4
  •  does not work with redux 2+

    does not work with redux 2+

    according to the docs here :http://redux.js.org/docs/advanced/Middleware.html a middleware is a function with this signature:

    const middleWare = store => next => action => { return next(action) }

    the current implementation is missing the first function which receives store. so i was getting an error "next is not a function"

    this fixes it

    opened by talarari 3
  • Update to redux@3.0.0

    Update to [email protected]

    I would really like to use this with the current version of redux. Right now it's limited to [email protected]. Do you expect breaking changes or might this just be done with changing the version requirement in package.json. I might try my luck but don't have any experience with testing this kind of thing.

    opened by simonwmn 7
Releases(v0.4.0)
  • v0.4.0(Aug 26, 2015)

  • v0.4.0-alpha(Jul 22, 2015)

    v0.4.0-alpha is a prerelease version, updated for compatibility with upcoming Redux 1.0 release.

    npm install redux-rx@prerelease
    

    Thanks to @frederickfogerty (https://github.com/acdlite/redux-rx/pull/4)

    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Jul 7, 2015)

    This release includes a new function createConnector(), which allows you to create Connector-like React components by transforming sequences of props and the store state (and a sequence of dispatchs, for correctness).

    (props$, state$, dispatch$) => childProps$
    

    createConnector() is actually a thin layer on top of react-rx-component, which is a generalized form of the same concept.

    Also new is a special version of bindActionCreators() that accepts either a dispatch function or a sequence of dispatch functions, useful for inside createConnector().

    import { createConnector } from 'redux-rx/react';
    import { bindActionCreators } from 'redux-rx; 
    
    Source code(tar.gz)
    Source code(zip)
Owner
Andrew Clark
React core at Facebook. Hi!
Andrew Clark
Skeleton React App configured with Redux store along with redux-thunk, redux persist and form validation using formik and yup

Getting Started with React-Redux App Some Configrations Needed You guys need to modify the baseUrl (path to your server) in the server.js file that is

Usama Sarfraz 11 Jul 10, 2022
A Higher Order Component using react-redux to keep form state in a Redux store

redux-form You build great forms, but do you know HOW users use your forms? Find out with Form Nerd! Professional analytics from the creator of Redux

Redux Form 12.6k Jan 3, 2023
redux-immutable is used to create an equivalent function of Redux combineReducers that works with Immutable.js state.

redux-immutable redux-immutable is used to create an equivalent function of Redux combineReducers that works with Immutable.js state. When Redux creat

Gajus Kuizinas 1.9k Dec 30, 2022
A chart monitor for Redux DevTools https://www.npmjs.com/package/redux-devtools-chart-monitor

Redux DevTools Chart Monitor This package was merged into redux-devtools monorepo. Please refer to that repository for the latest updates, issues and

Redux 293 Nov 13, 2022
A simple app for study react with redux, redux saga and typescript.

React com Redux, Redux-Saga e TypeScript. ?? Uma aplicação simple para entender o funcionamento do Redux e a melhor maneira de utiliza-lo junto com o

João Marcos Belanga 1 May 24, 2022
Redux - Create forms using Redux And React

Exercício de fixação Vamos criar formulários utilizando Redux! \o/ Antes de inic

Márcio Júnior 2 Jul 21, 2022
A lightweight state management library for react inspired by redux and react-redux

A lightweight state management library for react inspired by redux and react-redux

null 2 Sep 9, 2022
Official React bindings for Redux

React Redux Official React bindings for Redux. Performant and flexible. Installation Using Create React App The recommended way to start new apps with

Redux 22.5k Jan 1, 2023
DevTools for Redux with hot reloading, action replay, and customizable UI

Redux DevTools Developer Tools to power-up Redux development workflow or any other architecture which handles the state change (see integrations). It

Redux 13.3k Jan 2, 2023
Ruthlessly simple bindings to keep react-router and redux in sync

Project Deprecated This project is no longer maintained. For your Redux <-> Router syncing needs with React Router 4+, please see one of these librari

React Community 7.9k Dec 30, 2022
The official, opinionated, batteries-included toolset for efficient Redux development

Redux Toolkit The official, opinionated, batteries-included toolset for efficient Redux development (Formerly known as "Redux Starter Kit") Installati

Redux 8.9k Dec 31, 2022
Thunk middleware for Redux

Redux Thunk Thunk middleware for Redux. npm install redux-thunk yarn add redux-thunk Note on 2.x Update Most tutorials today assume that you're using

Redux 17.5k Dec 31, 2022
Logger for Redux

Logger for Redux Now maintained by LogRocket! LogRocket is a production Redux logging tool that lets you replay problems as if they happened in your o

null 5.7k Jan 1, 2023
Selector library for Redux

Reselect Simple “selector” library for Redux (and others) inspired by getters in NuclearJS, subscriptions in re-frame and this proposal from speedskat

Redux 18.8k Dec 27, 2022
An alternative side effect model for Redux apps

redux-saga redux-saga is a library that aims to make application side effects (i.e. asynchronous things like data fetching and impure things like acce

Redux-Saga 22.4k Jan 5, 2023
Declarative Side Effects for Redux

Redux Data FX Declarative Side Effects for Redux. It helps you keep your business logic and effectful code separate. The idea is simple: in addition o

Matthieu Béteille 53 Jun 30, 2021
Analytics middleware for Redux

redux-analytics Analytics middleware for Redux. $ npm install --save redux-analytics Want to customise your metadata further? Check out redux-tap. Usa

Mark Dalgleish 490 Aug 5, 2022
:recycle: higher order reducer to add undo/redo functionality to redux state containers

redux undo/redo simple undo/redo functionality for redux state containers Protip: Check out the todos-with-undo example or the redux-undo-boilerplate

Daniel Bugl 2.8k Jan 1, 2023
Redux bindings for client-side search

redux-search Higher-order Redux library for searching collections of objects. Search algorithms powered by js-worker-search. Check out the live demo a

Brian Vaughn 1.4k Jan 2, 2023