Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

reflux

reflux164.3kBSD-3-Clause6.4.1TypeScript support: definitely-typed

A simple library for uni-directional dataflow application architecture inspired by ReactJS Flux

reflux, react, flux, architecture, dataflow, action, event, data

readme

RefluxJS

A simple library for unidirectional dataflow architecture inspired by ReactJS Flux.

NPM Version Bower Version Build Status NPM Downloads

Sauce Test Status


Installation

You can currently install the package as a npm package, a bower component, or import it from a CDN.

NPM

The following command installs RefluxJS as a npm package:

npm install reflux

Then, in your script, you can gain a reference to RefluxJS like so: var Reflux = require('reflux');

Bower

The following command installs reflux as a bower component that can be used in the browser:

bower install reflux

Then the files may be imported into your html file via bower_components/reflux/dist/reflux.js or bower_components/reflux/dist/reflux.min.js. At that point a Reflux variable will be globally available to you. It is suggested that you import RefluxJS after React.

CDN

RefluxJS is available at jsdelivr.

You may import the CDN files directly through a script tag. At that point a Reflux variable will be globally available to you. It is suggested that you import RefluxJS after React.


Overview

The main function of Reflux is to introduce a more functional programming style architecture by eschewing MVC like pattern and adopting a single data flow pattern.

+---------+       +--------+       +-----------------+
¦ Actions ¦------>¦ Stores ¦------>¦ View Components ¦
+---------+       +--------+       +-----------------+
     ^                                      ¦
     +--------------------------------------+

The pattern is composed of actions and data stores, where actions initiate new data to pass through data stores before coming back to the view components again. If a view component has an event that needs to make a change in the application's data stores, they need to do so by signaling to the stores through the actions available.


Usage

For usage, you need to create actions which can be called from React components. Those actions are listened to by stores which hold and update data. In turn those stores are hooked up to React components and set state within them as it is updated within the store.

Therefore the 3 main concepts to know are:

  1. creating actions
  2. creating stores
  3. hooking stores to React components

Creating Actions

Create an action by calling Reflux.createAction with an optional options object.

var statusUpdate = Reflux.createAction();

An action is a function object that can be invoked like any other function.

statusUpdate(data); // Invokes the action statusUpdate

There is also a convenience function for creating multiple actions.

var Actions = Reflux.createActions([
    "statusUpdate",
    "statusEdited",
    "statusAdded"
]);

// Actions object now contains the actions
// with the names given in the array above
// that may be invoked as usual

Actions.statusUpdate();

More on Actions:

Actions can also:

  • load files asynchronously with child actions
  • do preEmit and shouldEmit checking
  • have many shortcuts for easy usage

See Reflux Action Documentation for more.


Creating Stores

Create a data store much like ReactJS's own React.Component by creating a class extending Reflux.Store. The store has a state property much like a component, and uses setState like a component as well. You may set up all action listeners in the constructor and register them by calling the store's own listenTo function.

class StatusStore extends Reflux.Store
{
    constructor()
    {
        super();
        this.state = {flag:'OFFLINE'}; // <- set store's default state much like in React
        this.listenTo(statusUpdate, this.onStatusUpdate); // listen to the statusUpdate action
    }

    onStatusUpdate(status)
    {
        var newFlag = status ? 'ONLINE' : 'OFFLINE';
        this.setState({flag:newFlag});
    }
}

In the above example, whenever the action statusUpdate is called, the store's onStatusUpdate callback will be called with whatever parameters were sent in the action. E.g. if the action is called as statusUpdate(true) then the status argument in the onStatusUpdate function is true.

Stores also integrate easily with sets of actions via things like this.listenables. When an actions object (or an Array of multiple actions objects) is applied to this.listenables you may automatically add listeners simply by naming convention. Just name the functions either after the action name (such as actionName, or the camelcased action name preceded with "on", (such as onActionName).

var Actions = Reflux.createActions(['firstAction', 'secondAction']);

class StatusStore extends Reflux.Store
{
    constructor()
    {
        super();
        this.listenables = Actions;
    }

    onFirstAction()
    {
        // calls on Actions.firstAction();
    }

    onSecondAction()
    {
        // calls on Actions.secondAction();
    }
}

More on Stores:

Reflux stores are very powerful. They can even do things like contribute to a global state that can be read and set for partial or full-state time-travel, debugging, etc.

See Reflux Store Documentation to learn more about stores.


Hooking Stores to Components

Once you've created actions and stores, now the last step in working RefluxJS is to hook those stores to a React component.

This is done as simply as extending Reflux.Component instead of React.Component and setting the store(s) to use. Reflux.Component itself extends React.Component, so you use them the exact same. The only difference is that Reflux.Component allows you to set stores for the component to get state from:

class MyComponent extends Reflux.Component
{
    constructor(props)
    {
        super(props);
        this.state = {}; // our store will add its own state to the component's
        this.store = StatusStore; // <- just assign the store class itself
    }

    render()
    {
        var flag = this.state.flag; // <- flag is mixed in from the StatusStore
        return <div>User is {flag}</div>
    }
}

When the component mounts it will either create a singleton instance of StatusStore (if one isn't already made) or use an already made singleton (if it was already created by another component that uses the store).

Of important note is that you can:

  1. Set multiple stores by setting this.stores (the plural) and setting it to an Array of store classes.
  2. Set a this.storeKeys Array to restrict only certain parts of the store being mixed into the component state.

There is also a mapStoreToState method in the documentation for those that want absolute control over how a store's state is mapped to a component.

class MyComponent extends Reflux.Component
{
    constructor(props)
    {
        super(props);
        this.state = {type:'admin'}; // <- note that we can still use normal state
        this.stores = [StatusStore, AnotherStore];
        this.storeKeys = ['flag', 'info'];
    }

    render()
    {
        var flag = this.state.flag;
        var info = this.state.info;
        var type = this.state.type;
        return <div>User is {flag}, info: {info}, type: {type}</div>
    }
}

The above will mix in properties from the state of both StatusStore and AnotherStore. However, because of this.storeKeys it will only mix in the properties flag and info from them. So any other properties within those stores will not get mixed in. So even if a store contained a type property in its state it would not get mixed in, and the type value we set as a normal part of the component state is safe.

More on using Reflux style components:

Reflux's simple and intuitive way of integrating stores into components is easy and powerful. You can aggregate stores together on a component-by-component basis, filter which parts of the stores come through and which don't, or even do a detailed manual mapping of exactly how you want the state from stores to map to the state in a particular component.

See Reflux Style Component Documentation to learn more.


Documentation

What you've just read is a "view from 10,000 feet" type overview of getting started with RefluxJS. For serious learning see the documentation.

changelog

Changelog

Check for latest changes on the milestones page.

For updates on reflux core methods, check the CHANGELOG at reflux-core project.

v6.4.1

  • NOTE: New MyStore.state shortcut (from 6.4.0) is not available in IE10 and below, use accordingly in your projects.
  • Remove test for it so that it doesn't fail, and is undocumented feature for now, until the day we can drop IE9 and IE10.

v6.4.0

  • Improved on class extending function used internally.
  • Made that extending function available externally at Reflux.utils.inherits(NewClass, InheritsFrom) so that it can be used for testing.
  • Made MyStore.state work as shortcut access to MyStore.singleton.state (not available in IE9 and IE10, plan usage accordingly for your project).

v6.3.0

  • Added Reflux.PureComponent which extends from React.PureComponent instead of React.Component.

v6.2.0

  • React.Component constructor arguments for context and updater added to Reflux.Component contructor.

v6.1.0

  • Documentation about Action listening/unsubscribing added.
  • Reflux.serverMode added, only adds listeners when hooking store to component if not in server mode, eliminating memory leak.
  • Bugfix with unmounting of reflux components that did not have any store attached to them.

v6.0.0

  • Switch to new docs.
  • Updated to reflux-core v1.0.0.
  • Allow complex definitions for child actions instead of just string for action name.
  • Breaking change: actions are sync by default unless child actions are involved.

v5.0.4

  • Workaround to babel proto issue with old browsers.
  • Continued documentation refactoring (viewable in new-README.md).
  • Minor doc fixes.

v5.0.3

  • Implemented Reflux.initStore (basically clone of Reflux.initializeGlobalStore but can be used more broadly).
  • Deprecate Reflux.initializeGlobalStore in favor of more broadly usable Reflux.initStore.
  • Major documentation refactor started, but not implemented yet (viewable in new-README.md).
  • Updated to run on reflux-core v0.4.2, which has more broad importing support.

v5.0.2

  • Reduced the need for defineReact by better detecting of React.
  • Updated to run on reflux-core v0.4.1, which solves some memory leaks.

v5.0.1

  • Adding of full ES6 API, most notably Reflux.Component and Reflux.Store (and their sub-methods/properties). Also defineReact, initializeGlobalStore, GlobalState, getGlobalState, setGlobalState.

v0.4.x

  • ??

v0.3.0

  • Bumped up along with breaking changes in reflux-core.

v0.2.13

  • Fixed React dependency #425
  • Example on README corrected #406

v0.2.12

v0.2.11

  • Using setImmediate if available. Fixes issue with IE10+, see #374.

v0.2.10

  • Exposing Reflux.utils #253
  • Fixing connectFilter #371
  • Added links in README to extensions and plugins

Breaking changes to undocumented features

  • Fixed circular referencing to the index js file. Should fix issues building with bower package. This means you can't replace the ActionMethods and StoreMethods objects (as the previous unit tests did), you have to add properties to them.

  • Removed native-promise-only dependency. Reflux does an initial check for Promises and will instead create async actions using triggerAsync instead of triggerPromise if Promise is missing from the environment. Do use a Promise polyfill or your own Promise library if you plan to use this behavior. #302

v0.2.9

  • Fixes issue with a join check #272.
  • Added links to README. See #341, #361

v0.2.8

See #345.

  • Fixes #239, checks for component mounted state before trying to mount component
  • Adds more example apps to README
  • Fixes some typo's in the readme
  • Improves documentation on action handlers in stores
  • Updates dependencies
  • Specifies react compatibility via peerDependencies

v0.2.7

  • Fixed IE8 errors and warnings #286, #270
  • Ensure triggerPromise original promise #229
  • Fixed aborted callbacks #227

v0.2.6

  • Fixed catch call in Promises #267
  • Promise and EventEmitter is now properly exported #258, #253
  • Getters in stores were accidentally invoked #231, #230
  • Asynchronous actions will now return promises #223, #216, #259
  • dist folder is now available again in npm package #266
  • Fixes to README file #260, #247, #244, #240, #236, #235, #234

v0.2.5

v0.2.4

v0.2.3

v0.2.2

  • Fixed circular dependency issue that caused browserify builds not to work as expected #129 #138
  • Bind store methods before init() method executes. #168
  • Clarify the meaning of "FRP". #161
  • Child (async) actions and promise handling #140

v0.2.1

  • IE8 trailing comma bug fix #145
  • Multiple use of Reflux.connect bug fix #142, #143
  • Added .npmignore file, removing non-essential files from npm install #125

v0.2.0

  • Breaking change: Set initial state before componentDidMount (in Reflux.connect) #117
  • Allow extension of actions and stores (with Reflux.ActionMethods and Reflux.StoreMethods) #121
  • Automatically bind store methods #100
  • Bugfix: Connect and listenermixin combo #131

v0.1.14, v0.1.15

  • You may now stop listening to joined listenables individually #96.
  • Reflux will now throw an error if you attempt to join less than two listenables #97.

v0.1.13

  • Added more join methods, i.e. listener.joinLeading, listener.joinTrailing, listener.joinConcat and listener.joinStrict #92.
  • Actions can be set to sync or async trigger #93.
  • And various bug fixes. Check the milestone page.

v0.1.12

v0.1.9, v0.1.10, v0.1.11

v0.1.8

  • Added Reflux.connect, Reflux.listenTo, listenToMany conveniences. See #63 and #75
  • Stores may now use a listenables prop #63 to automatically register actions to callbacks
  • preEmit may now map or transform the action payload by returning something. See 58 and #78
  • Reflux now exposes a keep for easier introspection on actions and stores #56
  • Added mixin interfaces ListenerMethods and PublisherMethods making it possible for users to extend Reflux's actions and stores. See #45

v0.1.7

  • Added support for initial data handling #49
  • Added CHANGELOG.md #50
  • Bug: Unregistered actions could not be reregistered #47

v0.1.6

  • Added possibility to join actions and stores with Reflux.all #27, #28
  • Added circular dependency check #26

v0.1.5

  • Bug fix

v0.1.4

  • Action functors are now deferred #22, #23
  • Added web tests using testling.ci #20

v0.1.3

  • Added hooks preEmit and shouldEmit for actions #16
  • Various bug fixes and .jshintrc file created for grunt build

v0.1.2

  • Added ListenerMixin useful for React components #7
  • Using eventemitter3 instead #4

v0.1.1

  • Added convenience function to create multiple actions #6
  • Bug: createStore's unsubscribe function was broken #5

v0.1.0

  • Removed lodash dependency #1