Home

Awesome

Flurx

Following the tradition of ridiculously titled Flux variations, I'm proud to announce Flurx.

Flux using RxJS, advocating but not strictly enforcing immutable data structures.

Description

It's a very thin wrapper around Rx.Subject for Actions and Rx.BehaviorSubject for Stores, basically adding only two methods:

In a nutshell:

Installation

npm install flurx

Example

import React from 'react';
import {Store, Action} from 'flurx';

const LoginAction = Action.create();
const LoginActionSuccess = Action.create();
const LoginActionFailure = Action.create();

class LoginStore extends Store {
  constructor() {
    super({
      isLoggedIn: false,
      username: null,
      warn: null
    });

    this.register(LoginAction, this.onLogin);
    this.register(LoginActionSuccess, this.onLoginSuccess);
    this.register(LoginActionFailure, this.onLoginFailure);
  }

  onLogin(store, username, password) {
    if (!store.isLoggedIn) {
      getJSON('/login', {username, password})
        .then(LoginActionSuccess)
        .catch(LoginActionFailure);

      return Object.assign(store, {
        isLoggedIn: true,
        username,
        warn: null
      });
    }

    return store;
  }

  onLoginSuccess(store, result) {
    return Object.assign(store, {
      isLoggedIn: true,
      username: result.username
      warn: null
    });
  }

  onLoginFailure(store, err) {
    return Object.assign(store, {
      isLoggedIn: false,
      username: null,
      warn: err.message
    })
  }
}

const loginStore = new LoginStore();

const LoginComponent = React.createClass({
  getInitialState() {
    return loginStore.getValue();
  },

  componentDidMount() {
    loginStore.subscribe(store => {
      this.setState(store);
    });
  },

  onSubmit(e) {
    e.preventDefault();

    const username = this.refs.username.getValue().trim();
    const password = this.refs.password.getValue().trim();

    if (!username || !password) {
      return;
    }

    LoginAction(username, password);
  },

  render() {
    return (
      !this.state.isLoggedIn ?
        <form method="GET" action="/login" onSubmit={this.onSubmit}>
          {this.state.warn != null ? <p>{this.state.warn}</p> : null}
          <input ref="username" name="username" type="text"/>
          <input ref="password" name="password" type="password"/>
          <button type="submit">Login</button>
        </form> :
        <p>Welcome, {this.state.username}.</p>
    );
  }
});