Code Monkey home page Code Monkey logo

fflux's Introduction

fflux.js

Build Status Code Climate Test Coverage

Examples:

Contents:

What is FFlux?

  • Dispatcher, Store, React mixin + simple API to use them together
  • Two types of stores: mutable & immutable
  • No singletons (can be used for isomorphic apps)
  • 100% test coverage
  • Detailed error messages (using facebook's invariant)
  • Modular: use only parts you need

Roadmap

  • Finalize the API
  • Separate stores to mutable and immutable
  • Write "Getting Started"
  • Make an example of isomorphic app
  • Make an example for Riot.js
  • Find a way to avoid using mixins

Installation

npm

npm install fflux

bower

bower install fflux

Dispatcher

FFlux dispatcher extends standard Flux.Dispatcher implementation.

var dispatcher = new FFlux.Dispatcher();

// ...

dispatcher.dispatch('SOME_ACTION', payload);

Dispatcher API

  • register - register store in dispatcher
    After registration, store will receive dispatcher's actions

    dispatcher.register(store);
  • unregister - unregister store from the dispatcher
    Store wouldn't receive actions any more.

    dispatcher.unregister(store);
  • dispatch - dispatch action to the stores:

    dispatcher.dispatch(actionName, actionPayload);`
  • waitFor - wait for another store to process action first

    var someStore = FFlux.ImmutableStore();
    
    dispatcher.waitFor([someStore]);

Actions

Actions are used for sending messages to dispatcher:

dispatcher.dispatch('SOME_ACTION', data);

Where data is a JS object with action's payload.

Action Creators

Action Creators are commonly used to make a bridge between front-end and back-end parts of your application. All async stuff should happend here.

var dispatcher = require('dispatcher');

var ActionCreatorExample = {
  /**
   * Fetch data from server
   * @param {Object} criteria
   */
  fetchData: function(criteria) {
    $.get(someUrl, criteria, function(response) {
      dispatcher.dispatch('FETCH_DATA', response);
    });
  },

  /*
   * Post data to the server
   * @param {Object} data
   */
  postData: function(data) {
    $.post(someUrl, data, function(response) {
      dispatcher.dispatch('POST_DATA', response);
    });
  }
};

Stores

In fflux, you can use mutable and immutable stores. If you want to work with store's state as native javascript object - you should use mutable store. If you prefer immutable structures, immutable stores - is your choice. Both stores have the same API:

Store API

  • setState - merge current state with the one provided
    Hint: if you're using mutable stores, every setState will emit change event. In the case of immutable stores, change event will be emitted only if new state is different from the current one.

    store.setState({ key: value });
  • replaceState - replace current state with a given one

    store.replaceState({ key: value });
  • registerAction - register action handler

    store.registerAction(actionName, actionHandler);
  • unregisterAction - unregister action handler

    store.unregisterAction(actionName);

Mutable Store

Mutable store is a basic store you have in fflux:

var store = new FFlux.MutableStore({
  /**
   * In this property we declare list
   * of the actions we're interested in.
   */
  actions: {
    'SOME_ACTION': 'someMethod'
    'OTHER_ACTION': 'otherActionHandler'
  },

  /**
   * Get initial state
   * Works the same way as in React
   * @return {Any} Initial state
   */
  getInitialState: function() {
    return {};
  }

  /**
   * Handler for SOME_ACTION
   * @param {Object} data Payload
   * @return {Void}
   */
  someActionHandler: function(data) {
    this.setState(data);
  },

  /**
   * Handler for OTHER_ACTION
   * @param {Object} data Payload
   * @return {Void}
   */
  otherActionHandler: function(data) {
    this.setState(data);
  }
});

Every handler could be a method name of the store instance or a standalone function. In every action handler you can use waitFor method as described here:

{
  /**
   * Some action's handler
   * @param {Object} data Payload
   * @return {Void}
   *
   * @description For invoke some function(s) only *after* other store
   * process action, we need to use `waitFor` method
   */
  someMethod: function(data) {
    /**
     * If we need to be sure, that some function will be called
     * only after `storage` store would process the action
     */
    dispatcher.waitFor([storage]);
  }
}

You can register/unregister action handlers dynamically after store initialization:

var store = new FFlux.MutableStore({...});

/**
 * Action handler function
 * @param {Object} data Payload
 * @return {Void}
 */
function actionHandler(data) {
  //...
}

/**
 * Register handler `actionHandler` for action `SOME_ACTION`
 */
store.registerAction('SOME_ACTION', actionHandler);

/**
 * Call `unregisterAction` for remove action handler
 */
store.unregisterAction('SOME_ACTION');

And the last, but not least: states. FFlux stores have a state like React components, so you can easily work with it using already familiar functions: setState, getState, replaceState and getInitialState.

Immutable store

Immutable store inherits form mutable store and enhances its functionality with immutable data.

var store = new FFlux.ImmutableStore();

/*
 * currentState will be empty Immutable.Map
 */
var currentState = store.getState();

/**
 * Mutator for `c` key in `a.b.c` path
 * @param  {Array} element 
 * @return {Immutable.List}
 */
function mutator(element) {
    return element.map(function(i) {
      return i * i;
    });
  }
}

/*
 * If we using immutable data, 
 * any manipulation with `currentState`
 * will create a new immutable object
 */
var newState = currentState
  .updateIn(['a', 'b', 'c'], mutator)
  .set('b', 'new key')
  .set('c', currentState.getIn(['a', 'b', 'c']));

// currentState is still the same (empty Immutable.Map)

store.replaceState(newState);

Any store state operation (e.g. setState or replaceState) will trigger change event only in the cases when previous state isn't equal to the new one.

View layer

FFlux is view-agnostic. The only thing that fflux provides you - a mixin for react to bind to store, which would add a storeDidUpdate funciton to handle store's update:

/**
 * Create some immutable store
 */
var store = new FFlux.ImmutableStore({...});

/**
 * React class to describe component
 */
var MyComponentClass = React.createClass({
  /**
   * Bind React view to listen `change` event of the `store`
   * @type {Array}
   */
  mixins: [FFlux.mixins.bind(store)],

  getInitialState: function() {
    return store.getState();
  },

  /**
   * After store emit `change` event
   * this function will be invoked
   * @return {Void}
   */
  storeDidUpdate: function() {
    this.setState(store.getState());
  },

  render: function() {
    var state = this.getState();
    return (
      <div>{state.get('something')}</div>
    );
  }
});

/**
 * That's it, now you can render `MyComponent` and
 * as soon as `store` will emit `change` event, 
 * your component will be redrawn
 */
React.render(<MyComponent />, document.body);

fflux's People

Contributors

kirjs avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.