acdlite/flummox

View on GitHub
docs/dist/flummox/data/allDocs.json

Summary

Maintainability
Test Coverage
[{"path":"index","content":"Flummox\n=======\n\n[![build status](https://img.shields.io/travis/acdlite/flummox.svg?style=flat-square)](https://travis-ci.org/acdlite/flummox)\n[![Test Coverage](https://img.shields.io/codeclimate/coverage/github/acdlite/flummox.svg?style=flat-square)](https://codeclimate.com/github/acdlite/flummox)\n[![npm downloads](https://img.shields.io/npm/dm/flummox.svg?style=flat-square)](https://www.npmjs.com/package/flummox)\n[![npm version](https://img.shields.io/npm/v/flummox.svg?style=flat-square)](https://www.npmjs.com/package/flummox)\n\nIdiomatic, modular, testable, isomorphic Flux. No singletons required.\n\n```\n$ npm install --save flummox\n```\n\nJoin the **#flummox** channel of the [Reactiflux](http://reactiflux.com/) Slack community.\n\n[![Join the chat at https://gitter.im/acdlite/flummox](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/acdlite/flummox?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\n* [API documentation](flummox/docs/api.md)\n* [Quick start guide](flummox/docs/guides/quick-start.md)\n* [React integration guide](flummox/docs/guides/react-integration.md)\n\nFeatures\n--------\n\n- No singletons = isomorphism for free!\n- Robust yet minimal API inspired by React and ES6\n- Tiny. **~3.8kb (compressed and gzipped)**.\n- The dispatcher and constants are implementation details — no need to interact with them unless you want to.\n- Async actions [made simple with promises](flummox/docs/api/actions#asynchronous-actions). Pairs well with async-await, or your favorite promise library.\n- Easy [integration with React](flummox/docs/guides/react-integration) via fluxMixin and FluxComponent.\n- Support for [plain JavaScript class components](http://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html) in React 0.13.\n- Serialization/deserialization of stores, for faster page loads.\n- Centralized [debugging](flummox/docs/api/flux).\n- \"It's Just JavaScript\" — supports CoffeeScript, TypeScript, and any other compile-to-JS language.\n\n**Version 3.0 with official support for React 0.13 has been released! See the [changelog](https://github.com/acdlite/flummox/blob/master/CHANGELOG.md) and [upgrade guide](https://github.com/acdlite/flummox/blob/master/UPGRADE_GUIDE.md) for more information.**\n\n**Pssst...** Want to see an example of an isomorphic Flummox app? You're looking at one right now! [Check out the source](https://github.com/acdlite/flummox/tree/master/docs) to see how it's made.\n\nThe big idea\n------------\n\nThere are *sooo* many Flux libraries out there. What makes Flummox special?\n\nFlummox allows you to encapsulate your entire Flux set-up — stores, actions, constants, and the dispatcher — into a single class, with **zero singletons or global references**. It's as easy as\n\n```js\nconst flux = new Flux();\n```\n\nThere are many benefits to this approach, but the biggest one is that it makes isomorphism (running the same code on both the server and the client) incredibly straightforward.\n\n**Flummox is not a framework.** Rather than forcing a bunch of new concepts and complicated APIs upon you, Flummox embraces existing idioms from Flux, React, and ES6 — without being too prescriptive.\n\n#### Simple example\n\n\n```js\nimport { Actions, Store, Flummox } from 'flummox';\n\nclass MessageActions extends Actions {\n  newMessage(content) {\n    return content; // automatically dispatched\n  }\n}\n\nclass MessageStore extends Store {\n  constructor(flux) {\n    super();\n\n    const messageActions = flux.getActions('messages');\n    this.register(messageActions.newMessage, this.handleNewMessage);\n    this.messageCounter = 0;\n\n    this.state = {};\n  }\n\n  handleNewMessage(content) {\n    const id = this.messageCounter++;\n\n    this.setState({\n      [id]: {\n        content,\n        id,\n      },\n    });\n  }\n}\n\nclass Flux extends Flummox {\n  constructor() {\n    super();\n\n    this.createActions('messages', MessageActions);\n    this.createStore('messages', MessageStore, this);\n  }\n}\n\nconst flux = new Flux();\n\n// perform action\nflux.getActions('messages').newMessage('Hello, world!');\n```\n\n### Idiomatic\n\nIf you know Flux, you know Flummox. If you're not familiar with Flux, there are [many](http://facebook.github.io/flux/docs/overview.html#content) [great](https://medium.com/brigade-engineering/what-is-the-flux-application-architecture-b57ebca85b9e) resources available to get you up to speed.\n\nThe primary goal of Flummox is reduce the boilerplate involved in setting up Flux for your application, so the API has been kept as minimal and predictable as possible. It uses Facebook's dispatcher under the hood. It encourages (but does not require) the use of ES6 classes. The state API for stores mirrors the state API for React components. Everything works as you'd probably expect.\n\n### Modular\n\nThere are three classes in Flummox: Store, Actions, and Flux. They are completely independent from each other. For example, you can create a new Store without ever touching Flux or Actions. You can extend them, modify them, add mixins — if it's possible with JavaScript, you can do it.\n\nExamples in this document use ES6 class notation, but that's a pattern, not a requirement: underneath the hood, it's just JavaScript prototypical inheritance. It's compatible with CoffeeScript, TypeScript, and regular ES5 right out of the box.\n\n### Testable\n\nBecause Flummox does not rely on singletons, and each of the different classes can be instantiated independently from the others, it's really easy to write tests. A good example can be found in Flummox's own [test suite](https://github.com/acdlite/flummox/blob/master/src/__tests__/Store-test.js).\n\n### Isomorphic\n\nThis is a big one, and one of the biggest motivating factors for creating this library. Isomorphism is tricky or impossible in many other Flux libraries because they rely on singleton objects, spread out across multiple modules. Often they force you to use a separate API.\n\nAgain, because Flummox does not rely on singletons, you get isomorphism for free: just create a new Flux instance on each request! Here's a very basic example how that might look using Express and React:\n\n```js\n\n// shared/Flux.js\nclass Flux extends Flummox { ... }\n\n// server/app.js\napp.get(\"/\", function(req, res) {\n  const flux = new Flux();\n\n  res.send(\n    React.renderToString(<App flux={flux} />)\n  );\n});\n```\n\nFlummox also gives you the ability to serialize the initial state of your application on the server, send it down to the client as a string, and deserialize it before the initial render. While not required for isomorphism, it helps make the initial page load snappy by reducing unnecessary AJAX requests to the server.\n\nReact integration\n-----------------\n\nIntegrating Flummox with React is really easy. You can do it the long way by manually adding and removing event listeners, but that leads to a lot of boilerplate. Use FluxComponent and/or fluxMixin to subscribe to store changes.\n\nHere's a basic example:\n\n```js\nimport React from 'react';\nimport FluxComponent from 'flummox/component';\n\nclass OuterComponent extends React.Component {\n  render() {\n    return (\n      // Pass an array of store keys, or a map of keys to state getters\n      <FluxComponent connectToStores={['storeA', 'storeB']}>\n        <InnerComponent />\n      </FluxComponent>\n    );\n  }\n}\n```\n\nYou can subscribe to subsets of store state using custom state getters. Read all about it in the [React integration guide](flummox/docs/guides/react-integration).\n\n\nRoadmap\n-------\n\nFlummox is still quite new, but the core features are already in place. A big focus right now is improving the documentation, writing guides, and providing examples. Since Flummox's core innovation is its approach to isomorphism, I would like to make it especially easy for newcomers to learn how to use Flummox to create isomorphic applications.\n\nFeature requests and PRs are absolutely welcome, as long as they keep with the spirit of a minimal core API. Any additional features (e.g. undo-redo & versioning) are likely to be implemented as addons, rather than as part of the core.\n\n\nRecommended libraries\n---------------------\n\nFlummox is just Flux. It has no opinion on the rest of your stack. You don't even have to be using React. But in case you're interested, here are some recommended tools and libraries that complement Flummox well:\n\n* [React (of course!)](http://facebook.github.io/react/)\n* [Immutable.js](http://facebook.github.io/immutable-js/) — Using immutable data in your applications not only makes your application more performant, but it also simplifies state management in your stores. No more defensive copying! It also helps ensure isolation between stores by reducing the likelihood that you'll accidentally mutate a dispatched payload.\n* [React Router](https://github.com/rackt/react-router) — A complete routing solution for React, with excellent support for isomorphic applications.\n* [Babel](https://babeljs.io/) — Use next-generation JavaScript (ES6, and even some ES7) today. Once you've tried it, it's the only way to write JavaScript. Babel also very conveniently supports JSX compilation.\n\n\nInspiration and thanks\n----------------------\n\n* Facebook, obviously.\n* Pete Hunt's talk at React.js Conf 2015 [\"Full Stack Flux\"](https://www.youtube.com/watch?v=KtmjkCuV-EU). The idea of stores as essentially \"a reduce() + a change event\" was illuminating.\n* [alt](https://github.com/goatslacker/alt), a similar Flux library from which I shamelessly copied (ideas, not code)\n\nLicense\n-------\n\nMIT\n\nAndrew Clark [@acdlite](https://twitter.com/acdlite)\n"},{"path":"api/actions","content":"`Actions`\n=========\n\nCreate actions by extending from the base `Actions` class.\n\n```js\nclass MessageActions extends Actions {\n\n  // Methods on the prototype are automatically converted into actions\n  newMessage(content) {\n\n    // The return value from the action is sent to the dispatcher.\n    // It is also returned to the caller.\n    return content;\n  }\n\n  // Asynchronous functions are also supported: just return a promise\n  // This is easy using async-await\n  async createMessage(messageContent) {\n    const response = await serverCreateMessage(messageContent);\n    return await response.json();\n  }\n\n}\n```\n\nYou can also use a plain JavaScript object. When passed to `flux.createActions`, it will be converted into an Actions class.\n\n```js\n// Same as previous example\nconst MessageActions = {\n  newMessage(content) {\n    return content;\n  },\n\n  async createMessage(messageContent) {\n    const response = await serverCreateMessage(messageContent);\n    return await response.json();\n  }\n}\n```\n\nTesting\n-------\n\nThe return value of an action is dispatched automatically. It's also returned to the caller. This means it's possible to test actions completely independently from a Flux or Store instance. Here's how you'd test the example MessageActions from above:\n\n```js\n// Using mocha and chai-as-promised\nconst actions = new MessageActions();\n\nexpect(actions.newMessage('Hello world!')).to.equal('Hello world');\n\n// Assuming `serverCreateMessage()` has been mocked\nexpect(actions.createMessage('Hello world!')).to.eventually.deep.equal({\n  id: 1,\n  content: 'Hello world!',\n});\n```\n\n\nAsynchronous actions\n--------------------\n\nAsynchronous actions are actions that return promises. Unlike synchronous actions, async actions fire the dispatcher twice: at the beginning and at the end of the action. Refer to the [Store API](store.md) for information on how to register handlers for asynchronous actions.\n\nMethods\n-------\n\n### getActionIds\n\n```js\nobject getActionIds()\n```\n\nReturns an object of action ids, keyed by action name. (In most cases, it's probably more convenient to use `Flux#getActionIds()` instead.)\n\n\nAlso available as `getConstants()`\n"},{"path":"api/flux","content":"`Flux`\n======\n\nCreate Flux containers by extending from the base `Flux` (or `Flummox`) class.\n\n```js\nclass Flux extends Flummox {\n  constructor() {\n    super();\n\n    // Create actions first so our store can reference them in\n    // its constructor\n    this.createActions('messages', MessageActions);\n\n    // Extra arguments are sent to the store's constructor. Here, we're\n    // passing a reference to this Flux instance\n    this.createStore('messages', MessageStore, this);\n  }\n}\n```\n\nEncapsulate your stores and actions\n-------------------------------------\n\nFlummox is designed to be used without singletons. Instead, create a Flux class that encapsulates the creation of all your application's stores and actions, so that you can create new instances on the fly.\n\n```js\nconst flux = new Flux();\n```\n\n(Note that there's nothing technically stopping you from using singletons if you wish, but why would you want to?)\n\n\nDebugging\n---------\n\nLike Stores, Flux instances are EventEmitters. A `dispatch` event is emitted on every dispatch. Listeners are sent the dispatched payload. This can be used during development for debugging.\n\n```js\nflux.addListener('dispatch', payload => {\n  console.log('Dispatch: ', payload);\n});\n```\n\nAdditionally, an `error` event is emitted when errors occur as a result of an async action. This is both for convenience and to prevent error gobbling.\n\nMethods\n-------\n\n### createActions\n\n```js\nActions createActions(string key, function ActionsClass [, ...constructorArgs])\n```\n\nCreates an instance of `ActionsClass` and saves a reference to it. `constructorArgs` are passed to the constructor of `ActionsClass` on creation.\n\n### createStore\n\n```js\nStore createStore(string key, function StoreClass [, ...constructorArgs])\n```\n\nCreates an instance of `StoreClass`, registers the store's handlers with the dispatcher, and saves a reference to it. `constructorArgs` are passed to the constructor of `ActionsClass` on creation.\n\n### getStore\n\n```js\nStore getStore(string key)\n```\n\nGets an store instance by key.\n\n### removeStore\n\n```js\nStore removeStore(string key)\n```\n\nDeletes an instance of `StoreClass`, unregisters the store's handlers from dispatcher, and removes all store listeners.\n\n### getActions\n\n```js\nActions getActions(string key)\n```\n\nGets an actions instance by key.\n\n### getActionIds\n\n```js\nActions getActionIds(string key)\n```\n\nGets action ids for the given actions key. Internally calls `Actions#getActionIds`.\n\nAlso available as `getConstants()`.\n\n### removeActions\n\n```js\nActions removeActions(string key)\n```\n\nDeletes an actions instance by key.\n\nDispatcher methods\n------------------\n\nEvery Flux instance has its own dispatcher. You should try to avoid interacting with the dispatcher directly, but it is available (primarily for testing purposes) as `this.dispatcher`. Some convenience methods are also provided:\n\n### dispatch\n```\ndispatch(string actionId [, * body])\n```\n\nSimilar to the `dispatch()` method of the dispatcher itself, except instead of passing a payload, the payload is constructed for you, in the form:\n\n```js\n{\n  actionId,\n  body\n}\n```\n\nThis is used internally by Flummox: the `actionId` field is used to identify the source action, and `body` contains the value passed to store handlers. In your tests, you can use it to simulate a dispatch to your stores.\n\n### waitFor\n\n```\nwaitFor(Store store)\n```\n\nSimilar to the `waitFor()` method of the dispatcher itself, this can be used within a handler to wait for a different store to respond to the dispatcher before continuing. The operation is synchronous.\n\nInstead of passing a store, you can also pass a dispatcher token, or an array of tokens and stores.\n\nUsing a custom dispatcher\n-------------------------\n\n**tl;dr** Flummox uses the flux dispatcher from Facebook, but you can switch out whatever api compatible dispatcher you want.\n\n***\n\nUsually the dispatcher provided by Facebook is sufficient, but you aren't limited to using it if you find you need more than it provides.  If you want to have custom behavior when dispatching actions, you can provide a wrapper for the Facebook dispatcher that does what you want.  Or use something else entirely.  It's up to you.\n\nTo substitute a different dispatcher object just change the `constructor()` function of your flux object like this:\n\n```js\n\nclass Flux extends Flummox {\n  constructor() {\n    super();\n\n    this.dispatcher = new MyCustomDispatcher();\n  }\n}\n\n```\n\nJust remember, whatever object you provide has to follow the same api as the dispatcher from Facebook.  The easiest way to do that is to extend the Facebook dispatcher in a new class, and then provide whatever alternate or extended functionality you desire.\n\nFor instance, say you want to allow the dispatcher to receive actions for dispatching while it is in the middle of another action dispatch.  The standard dispatcher will complain that you cannot dispatch an action during another action.  There are good reasons for this, but perhaps you just want to queue up that action and have it execute when the current action is completed.  One easy way to do this would be to use `setTimeout()`.  To do this you would provide a dispatcher with slightly different dispatch functionality, like this:\n\n```js\n\nclass MyCustomDispatcher extends Dispatcher {\n  dispatch(...args) {\n    if (!this.isDispatching()) {\n      super.dispatch(...args); // This will execute the Facebook dispatcher's dispatch function.\n    } else {\n      setTimeout(() => { // We are currently dispatching, so delay this action using setTimeout\n        super.dispatch(...args);\n      }, 0);\n    }\n  }\n}\n\n```\n\nSerialization/deserialization\n-------------------------------\n\nIf you're building an isomorphic application, it's often a good idea pass the initial state of your application from the server to the client to avoid unecessary/duplicate HTTP requests. This is easy with Flux, since all of your application state is located in your stores.\n\nThis feature is opt-in on a store-by-store basis, and requires some additional set-up.\n\n### serialize\n\n```\nstring serialize()\n```\n\nReturns a serialized string describing the entire state of your Flux application.\n\nInternally, it passes each store's current state to the store's static method `Store.serialize()`. The return value must be a string representing the given state. If a store does not have a static method `serialize()`, or if it returns a non-string, it is ignored.\n\n### deserialize\n\n```\ndeserialize(string stateString)\n```\n\nConverts a serialized state string (as returned from `Flux#serialize()`) to application state and updates the stores.\n\nInternally, it passes the state string for each store (as returned from `Store.serialize()`) to the store's static method `Store.deserialize()`. The return value must be a state object. It will be passed to `Store#replaceState()`. If a store does not have a static method `deserialize()`, it is ignored.\n"},{"path":"api/fluxcomponent","content":"`FluxComponent`\n===============\n\n**In v3.0, FluxComponent requires React 0.13. If you're still on React 0.12, keep using Flummox 2.x until you're able to upgrade.**\n\nAccess the Flux instance and subscribe to store updates. Refer to the [React integration guide](../guides/react-integration.md) for more information.\n\n\n```js\n<FluxComponent connectToStores={{\n  posts: store => ({\n    post: store.getPost(this.props.post.id),\n  }),\n  comments: store => ({\n    comments: store.getCommentsForPost(this.props.post.id),\n  })\n}}>\n  <InnerComponent />\n</FluxComponent>\n```\n\nIn general, [it's recommended to use FluxComponent instead of fluxMixin](../guides/why-flux-component-is-better-than-flux-mixin.md).\n\nState getters\n-------------\n\nThe `stateGetter` prop can be used to control how state from stores are transformed into props:\n\n```js\n<FluxComponent\n  connectToStores={['posts', 'session']}\n  stateGetter={([postStore, sessionStore]) => ({\n    posts: store.getPostForUser(sessionStore.getCurrentUserId())\n  })}\n}}>\n  <InnerComponent />\n</FluxComponent>\n```\n\nThe `stateGetter` prop behaves differently depending on the value passed to the `connectToStores` prop, refer to [fluxMixin](fluxmixin.md) for more details.\n\n\nAccess flux with `this.props.flux`\n----------------------------------\n\nIn the child component, you can access the Flux instance with `this.props.flux`. For example, to perform an action:\n\n```js\nonClick(e) {\n  e.preventDefault();\n  this.props.flux.getActions('actionsKey').someAction();\n}\n```\n\nCustom rendering\n----------------\n\nWith FluxComponent, state from your stores is automatically passed as props to its children. This is nice for simple cases, especially when there's only a single child. But for more complex cases, or if you want direct control over rendering, you can pass a custom render function prop to FluxComponent:\n\n```js\n// Using children\n<FluxComponent connectToStores={{\n  posts: store => ({\n    post: store.getPost(this.props.postId),\n  })\n}}>\n  <InnerComponent />\n</FluxComponent>\n\n// Using custom `render` function\n<FluxComponent\n  connectToStores={{\n    posts: store => ({\n      post: store.getPost(this.props.postId),\n    })\n  }}\n  render={storeState => {\n    // Render whatever you want\n    return <InnerComponent {...storeState} />;\n  }}\n/>\n```\n\nProps\n-----\n\n### `flux`\n\nIndicates the [Flux instance](flux.md) to be used. It will be added to the context of all its nested components. If unset, it'll try to infer it from the context.\n\n### `connectToStores`\n\nThis prop has the same effect as passing the first argument to [fluxMixin](fluxmixin.md)'s `connectToStores()`.\n\n### `stateGetter`\n\nThis prop has the same effect as passing the second argument to [fluxMixin](fluxmixin.md)'s `connectToStores()`.\n\n### `render`\n\nOptionally overrides the rendering function, useful to control what state is passed down as props to components.\n"},{"path":"api/fluxmixin","content":"`fluxMixin`\n===========\n\nAccess the Flux instance and subscribe to store updates. Refer to the [React integration guide](../guides/react-integration.md) for more information.\n\nNote that fluxMixin is actually a function that returns a mixin, as the example below shows. The parameters are the same as those for `connectToStores()`, described below. On component initialization, `connectToStores()` is called and used to set the initial state of the component.\n\n```js\nimport fluxMixin from 'flummox/mixin';\n\nlet MyComponent = React.createClass({\n\n  mixins[fluxMixin(['storeA', 'storeB'])],\n\n  ...\n});\n```\n\nIn general, [it's recommended to use FluxComponent instead of fluxMixin](../guides/why-flux-component-is-better-than-flux-mixin.md).\n\nState getters\n-------------\n\nWhen connecting to stores with fluxMixin (and FluxComponent), you'll usually want to specify custom state getters.\n\nA state getter is a function which returns a state object for a given store. The state object is merged into the component state using `setState()`.\n\nThe default state getter returns the entire store state. You can specify null as a state getter to use the default state getter.\n\nHere's an example of a state getter map you would pass to either `fluxMixin()` or `connectToStores()`. The keys are store keys, and the values are state getter functions.\n\n```js\nfluxMixin({\n  posts: (store, props) =>({\n    storeA: store.getPost(props.post.id),\n  }),\n  comments: (store, props) => ({\n    comments: store.getCommentsForPost(props.post.id),\n  })\n});\n```\n\nIn some situations the data retrieved from one store depends on the state from another, you can use an array of store keys with a custom state getter to ensure the components state is updated when either store changes:\n\n```js\nfluxMixin(\n  ['posts', 'session'],\n\n  // An array of store instances are passed to the state getter; Instead of indexing\n  // into the stores array, ES6 array destructuring is used to access each store\n  // as a variable.\n  ([postStore, sessionStore]) => ({\n    posts: store.getPostForUser(sessionStore.getCurrentUserId())\n  })\n);\n```\n\nAccess flux with `this.flux`\n----------------------------\n\nYou can access the Flux instance with `this.flux`. For example, to perform an action:\n\n```js\nonClick(e) {\n  e.preventDefault();\n  this.flux.getActions('actionsKey').someAction();\n}\n```\n\n\nMethods\n-------\n\n### connectToStores\n\n```js\nconnectToStores(string storeKey [, function stateGetter])\nconnectToStores(Array<string> storeKeys [, function stateGetter])\nconnectToStores(object stateGetterMap [, function stateGetter])\n```\n\nSynchronize component state with state from Flux stores. Pass a single store key, an array of store keys, or a map of store keys to getter functions. You can also specify a custom state getter as the second argument, the default state getter will return the entire store state (a reduce is performed on the entire store state when using an array or store keys).\n\nWhen using an array of store keys, the custom state getter is called with an array of store instances (same order as keys) as the first argument; An array is used instead of separate arguments to allow for future versions of flummox to pass additional arguments to the stateGetter eg. `props`.\n\nOtherwise only a single store instance is passed to the custom state getter.\n\nReturns the initial combined state of the specified stores.\n\n**Usage note**: Generally, you should avoid calling this directly and instead pass arguments to `fluxMixin()`, which calls this internally.\n\n### getStoreState\n\n```\ngetStoreState()\n```\n\nReturns current combined state of connected stores.\n"},{"path":"api/higher-order-component","content":"Higher-order Flux Component\n===========================\n\n**Requires React 0.13. If you're still on React 0.12, use FluxComponent instead.**\n\nA higher-order component form of [FluxComponent](fluxcomponent.md). Here's an example from the [Flummox documentation app](https://github.com/acdlite/flummox/blob/master/docs/src/shared/components/HomeHandler.js#L15-L19):\n\n```js\nclass HomeHandler extends React.Component {\n  render() {\n    const { doc } = this.props;\n\n    if (!doc) return <span />;\n\n    return <Doc doc={doc} />;\n  }\n}\n\nHomeHandler = connectToStores(HomeHandler, {\n  docs: store => ({\n    doc: store.getDoc('index')\n  })\n});\n```\n\n**Note**: FluxComponent, fluxMixin, and the higher-order component implement the same [interface](https://github.com/acdlite/flummox/blob/master/src/addons/reactComponentMethods.js). Eventually the docs will updated to make this clearer.\n"},{"path":"api/index","content":"API\n===\n\nFlummox has three exports:\n\n* [Actions](api/actions.md)\n* [Store](api/store.md)\n* [Flux](api/flux.md) (also available as `Flummox`) This is the default export.\n\nIf you're using ES6 module syntax:\n\n```js\nimport { Flux } from 'flummox';\n```\n\nOr multiple classes at once:\n\n```js\nimport { Flux, Store, Actions } from 'flummox';\n```\n\nAddons\n------\n\nFlummox also comes with some addons. These are not part of the main export. That way, if you don't use them, they won't increase the size of your bundle.\n\n* [FluxComponent](api/fluxcomponent.md)\n* [fluxMixin](api/fluxmixin.md)\n* [Higher-order component](api/higher-order-component.md)\n\nRefer to the [React integration guide](../guides/react-integration.md) for details.\n\n```js\nimport fluxMixin from 'flummox/mixin';\nimport FluxComponent from 'flummox/component';\nimport connectToStores from 'flummox/connect';\n```\n"},{"path":"api/store","content":"`Store`\n=======\n\nCreate stores by extending from the base `Store` class.\n\n```js\nclass MessageStore extends Store {\n\n  // Note that passing a flux instance to the constructor is not required;\n  // we do it here so we have access to any action ids we're interested in.\n  constructor(flux) {\n\n    // Don't forget to call the super constructor\n    super();\n\n    // Register handlers with the dispatcher using action ids, or the\n    // actions themselves\n    const messageActions = flux.getActions('messages');\n    this.register(messageActions.newMessage, this.handleNewMessage);\n\n    // Set initial state using assignment\n    this.state = {};\n  }\n\n  // Define handlers as methods...\n  handleNewMessage() { ... }\n\n  // It's also useful to define accessor-style methods that can be used by\n  // your views on state changes\n  getMessage(id) { ... }\n}\n```\n\nManaging state\n--------------\n\nIn a Flux application, all application state is contained inside stores, and the state of a store can only be changed by the store itself. The sole point of entry for data in a store is via the dispatcher, but information sent through the dispatcher should be thought of not as data, but as messages *describing* data. This may seem like a distinction without a difference, but by sticking to this concept, it ensures that your stores remain isolated and free of the complicated dependencies you often find in MVC-style apps.\n\nBecause state is so crucial, Flummox is a little more opinionated than some other Flux libraries about how to manage it: for instance, all state must be stored in the `this.state` object. That being said, Flummox places no restrictions on the types of data you store, so interoperability with libraries like Immutable.js is a non-issue. If this sounds familiar, it's because the store API is heavily influenced by the [React component API](http://facebook.github.io/react/docs/component-api.html):\n\n* All state mutations must be made via `setState()`.\n* `this.state` is used to access the current state, but it should **never** be mutated directly. Treat `this.state` as if it were immutable.\n* As in React +0.13, initial state is set by assignment in the constructor.\n\nPerforming optimistic updates\n-----------------------------\n\nA common pattern when performing server operations is to update the application's UI optimistically — before receiving a response from the server — then responding appropriately if the server returns an error. Use the method `registerAsync` to register separate handlers for the beginning of an asynchronous action and on success and failure. See below for details.\n\nCustomizing top-level state type\n--------------------------------\n\nThe default top-level state type (`this.state`) is a plain object. You can add any type of data to this structure, as in React. However, if you want even more control over state management, you can customize the top-level state type by overriding the static Store method `Store.assignState()`. This method is used internally to perform state changes. The default implementation is essentially a wrapper around `Object.assign()`:\n\n```js\n// Default implementation\nstatic assignState(oldState, newState) {\n  return Object.assign({}, oldState, newState);\n}\n```\n\nThings to keep in mind when overriding `assignState()`:\n\n- Should be non-mutative.\n- `assignState(null, newState)` should not throw and should return a copy of `newState`.\n\nTo support React integration with FluxComponent, you should also override `Store#getStateAsObject()`, which returns a plain object representation of `this.state`. The default state getter uses the object returned by this function.\n\nMethods\n-------\n\n### register\n\n```js\nregister(function action | string actionId , function handler)\n```\n\nRegister a handler for a specific action. The handler will be automatically bound to the store instance.\n\nYou can register using either the action id or the action itself.\n\n**Usage note**: `register()` works for both async and sync actions. In the case of async actions, it receives the resolved value of the promise returned by the action.\n\n### registerAsync\n\n```js\nregisterAsync(function action | string actionId [, function begin, function success, function failure])\n```\n\nA register handler specifically for asynchronous actions (actions that return promises).\n\n- `beginHandler` is called at the beginning of the asynchronous action. It receives same arguments that were passed to the action.\n\n- `successHandler` works the same as if you registered an async action with `register()`: it is called if and when the asynchronous action resolves. It receives the resolved value of the promise returned by the action.\n\n- `failureHandler` is called if and when the asynchronous action is rejected. It receives the rejected value of the promise returned by the action (by convention, an error object).\n\nThis makes it easy perform to perform optimistic UI updates.\n\nIf any of the passed handlers are not functions, they are ignored.\n\n**Usage note**: `registerAsync(null, handler, null)` is functionally equivalent to `register(handler)`. If you don't need to respond to the beginning of an async action or respond to errors, then just use `register()`.\n\n### setState\n\n```js\nsetState(function|object nextState)\n```\n\nShallow merges `nextState` with the current state, then emits a change event so views know to update themselves.\n\nSimilar to React, multiple calls to `setState()` within the same handler are batched and applied at the end. Accessing `this.state` after calling `setState()` will return the existing value, not the updated value.\n\nYou can also do transactional state updates by passing a function:\n\n```js\nthis.setState(state => ({ counter: state.counter + 1 }));\n```\n\n### replaceState\n\n```js\nreplaceState(object nextState)\n```\n\nLike `setState()` but deletes any pre-existing state keys that are not in nextState.\n\n### forceUpdate\n\n```js\nforceUpdate()\n```\n\nEmits change event.\n\n**Usage note**: If you can, use `setState()` instead.\n\n\nEventEmitter methods\n--------------------\n\nFlummox stores are EventEmitters — specifically [eventemitter3](https://github.com/primus/eventemitter3) — so you can use any of the EventEmitter methods, the important ones being `addListener()` and `removeListener()`. Use these in your controller-views to subscribe to changes.\n\n**Usage note**: A `change` event is emitted automatically whenever state changes. Generally, this is the only event views should need to subscribe to. Unlike in MVC, Flux store events don't pass data around to different parts of your application; they merely broadcast that a change has occurred within a store, and interested parties should synchronize their state accordingly.\n\nDispatcher methods\n------------------\n\n### waitFor\n\n```js\nwaitFor(Store store)\n```\n\nWithin a handler, this waits for a different store to respond to the dispatcher before continuing. The operation is synchronous. E.g.\n\n```js\nsomeActionHandler() {\n  this.waitFor(someStore);\n  // someStore has completed, continue...\n}\n```\n\nInternally, it calls [`Dispatcher#waitFor()`](http://facebook.github.io/flux/docs/dispatcher.html#content).\n\nInstead of passing a store, you can also pass a dispatcher token, or an array of tokens and stores.\n\n**Usage note**: Because this method introduces dependencies between stores, you should generally try to avoid using it. Stores should be as isolated as possible from the outside world. If you find yourself relying on `waitFor()` often, consider rethinking how data flows through your app.\n\nStatic Methods\n-------\n\n### serialize(state)\n\nIf you use `Flux.serialize`, Flummox will try to call the static method `serialize` on all your stores. Flummox will pass the state object of the store to the method and expects a String\n\n### deserialize(state)\n\nIf you use `Flux.deserialize`, Flummox will try to call the static method `deserialize` on all your stores. Flummox will pass the appropriate serialized representation and expects an object, with which Flummox will call `replaceState` on your store.\n"},{"path":"guides/index","content":"Guides\n======\n\n- [Quick start](guides/quick-start)\n- [React integration](guides/react-integration)\n- [Why FluxComponent > fluxMixin](guides/why-flux-component-is-better-than-flux-mixin)\n"},{"path":"guides/quick-start","content":"Quick start\n===========\n\nThis document will help you get up and running with Flummox. We'll walk through the process of creating a sample Flux application for sending messages.\n\nLet's dive right in.\n\nInstallation\n------------\n\nThis part's pretty crucial :)\n\n```\n$ npm install --save flummox\n```\n\nOverview\n--------\n\nThere are three parts to Flummox: Actions, Stores, and Flux. Each is represented by a class, and you extend from the base class.\n\nHere's how we'll approach this walkthrough. I like to go in order of Flux data flow, because that just makes sense.\n\n1. Create some actions.\n2. Create a store that responds to those actions.\n3. Bring them together in a flux class.\n4. Use it in a view.\n\n### 1. Create some actions\n\nActions are groups of functions you call to send data through the dispatcher. (Sometimes these are actually referred to as *action creators*, while actions are the data structures that are sent through the dispatcher, but whatever. We're going to use *action* to refer to the function that triggers the dispatch.)\n\nTo create actions, just extend from the base Actions class and add some methods:\n\n```js\n\nimport { Actions } from 'flummox';\n\nclass MessageActions extends Actions {\n\n  createMessage(messageContent) {\n    return {\n      content: messageContent,\n      date: Date.now(),\n    };\n  }\n\n}\n\n```\n\nThat's it! Seriously. We just created a single action, `createMessage`, that takes in message content and returns an object with a message field and a date. The return value is then sent through the dispatcher automatically. (If you return `undefined`, Flummox skips the dispatch step.)\n\nThis is a pretty simple example, though. Often, your actions will need to perform some sort of async server operation before dispatching it to the stores. If you return a Promise, Flummox will wait for the Promise to resolve and then dispatch the unwrapped value. ES7's async-await pattern makes this easy. Let's update our example:\n\n```js\nclass MessageActions extends Actions {\n\n  async createMessage(messageContent) {\n    try {\n      return await serverCreateMessage(messageContent);\n    } catch (error) {\n      // handle error somehow\n    }\n  }\n\n}\n```\nYou can also do this longhand without async-await, but why would you ever want to? Anyway, you have the option.\n\nYou may have noticed that we haven't used any constants. \"Hey, that's not idiomatic Flux!\" Flummox *does* have constants, but they're treated as an implementation detail. Constants are generated for each action, and automatically sent through the dispatcher along with your payload. Because there's a one-to-one relationship between constants and actions, in Flummox we refer to them as *action ids*. Generally, the only time you do need to worry about action ids is when you're registering your stores to handle certain actions. Speaking of which...\n\n### 2. Create a store that responds to those actions\n\nStores manage the state of your application. Usually, you have one store per resource or \"thing\" you want to keep track of — in our case, messages. The key thing to understand about stores is that they cannot (or rather, should not) be altered from the outside; they receive messages from the dispatcher and respond accordingly. If you're new to Flux, this may seem like a distinction without a difference, but it's crucial.\n\nHere's how you create a store in Flummox. Like with Actions, create a class that extends from the base class:\n\n```js\nimport { Store } from 'flummox';\n\nclass MessageStore extends Store {\n\n  constructor(flux) {\n    super(); // Don't forget this step\n\n    const messageActionIds = flux.getActionIds('messages');\n    this.register(messageActionIds.createMessage, this.handleNewMessage);\n\n    this.state = {\n      messages: [],\n    };\n  }\n\n  handleNewMessage(message) {\n    this.setState({\n      messages: this.state.messages.concat([message]),\n    });\n  }\n\n}\n```\n\nThis should look very familiar to you if you've used ES6 classes to create components in React 0.13+:\n\n* Like React, set initial state by assigning to `this.state` in the constructor.\n* Like React, update state by using `this.setState()`, which shallow merges new state with old state.\n* Like React, multiple calls to `this.setState()` are batched.\n\nStores are EventEmitters. This lets views listen for changes and stay in sync. A change event is emitted automatically whenever you call `this.setState()`. If you like, you can also emit events manually using the EventEmitter API (`this.emit()`), though it's recommended to just rely on `this.setState()`.\n\nThe one bit of API that's new is `this.register(actionId, handler)`. This registers a store method with the dispatcher. Actually, it will accept any function, not just methods... but you probably want to stick to methods (except for testing purposes).\n\nIn this example, the store's constructor expects a single argument, `flux`. This is not a required argument (notice we're not passing it to `super()`); it's a pattern we're using so we have access to our message action ids. I'll explain this in the next section.\n\n### 3. Bring them together in a flux class\n\nThe Flux class unifies our stores and actions, along with a dispatcher, into a single, self-contained instance.\n\n```js\nimport { Flux } from 'flummox';\n\nclass AppFlux extends Flux {\n\n  constructor() {\n    super();\n\n    this.createActions('messages', MessageActions);\n\n    // The extra argument(s) are passed to the MessageStore constructor\n    this.createStore('messages', MessageStore, this);\n  }\n\n}\n```\n\n`createActions(key, ActionsClass, ...args)` and `createStore(key, StoreClass, ...args)` take a unique string key along with the classes we defined in the previous sections. There's not much magic going on here: under the hood, Flummox creates instances of your classes using the `new` operator, then stashes a reference to them internally.\n\nYou can access a Flux instance's actions and stores using `getActions(key)` and `getStore(key)`.\n\nThere's an additional method for accessing action ids: `getActionIds(key)`. This is the method we used in the MessageStore class we created above, in order to register the store's action handler. That's why we're passing our Flux instance to the constructor of MessageStore. To reiterate, this isn't a requirement; just a recommended pattern.\n\nEach Flux instance comes with its own dispatcher. Like constants, the dispatcher is treated as an implementation detail. The closest you'll come to interacting with it in most cases is the `Store#register(actionId, handler)` method discussed above. However, if you want to access the dispatcher directly, you can reference the `dispatcher` property of the Flux instance.\n\nSo, now we have an AppFlux class that encapsulates our entire Flux set-up! Now we just create an instance:\n\n```js\nconst flux = new AppFlux();\n```\n\nBecause everything is self-contained, you can create as many independent instances as you want. The reason this is so cool is that you get isomorphism for free: just create a new instance for each request.\n\n### 4. Use it in a view\n\n(Flummox/Flux can be used with any view library, of course, but I'm going to assume you're cool and using React.)\n\nSo how do you use Flux in your view components? With a traditional Flux library, we'd use a singleton. And if you want to do that, that's perfectly fine. Just create a module that exports a Flux instance and you're good to go. But again, this won't do on the server, because you need a way to 1) deal with multiple requests, and 2) isolate user-specific data. Instead, with Flummox, we create a new Flux instance for every request.\n\nHowever, manually passing your Flux instance as props down the component tree isn't the best solution. Instead, use fluxMixin and/or FluxComponent. Under the hood, they use React context to expose your Flux instance to arbitrarily nested views. They also make it stupidly easy to subscribe to store updates:\n\n```js\n\nclass MessagesView extends React.Component {\n\n  render() {\n    return (\n      <FluxComponent connectToStores={{\n        messages: store => ({\n          messages: store.messages\n        })\n      }}>\n        // MessageList is injected with a `messages` prop by FluxContainer\n        <MessageList />\n      </FluxComponent>\n    );\n  }\n\n}\n\n```\n\nRead more in the [React integration guide](react-integration).\n\nAnd there you go! I hope this guide was helpful.\n"},{"path":"guides/react-integration","content":"# React integration guide\n\nIf you're using Flummox, you're probably also using React. To make React integration incredibly simple, Flummox comes with some optional goodies: [FluxComponent](/flummox/docs/api/fluxcomponent) and [fluxMixin](/flummox/docs/api/fluxmixin). Both have essentially the same functionality — in fact, the component is mostly just a wrapper around the mixin. However, in the spirit of React, the component form is preferred. (Read more about [why FluxComponent is preferred](why-flux-component-is-better-than-flux-mixin).)\n\n```js\nimport FluxComponent from 'flummox/component';\nimport fluxMixin from 'flummox/mixin';\n```\n\nThis guide discusses how to use FluxComponent to integrate Flummox with React.\n\n**In v3.0, FluxComponent requires React 0.13. If you're still on React 0.12, keep using Flummox 2.x until you're able to upgrade.**\n\n## Accessing the Flux instance\n\n**tl;dr** FluxComponent gives you easy access to your Flux instance from anywhere in your component tree using only components and props.\n\n***\n\nUnlike most other Flux libraries, Flummox doesn't rely on singletons, because singletons don't work well on the server. The one downside of this approach is that in order to access your stores and actions, you can't just require a module: you have to pass your Flux instance through your component tree. You could do this by manually passing props from one component to the next, but that's not a great solution for components that are nested more than a few levels down.\n\nA better approach is to use context, which exposes data to arbitrarily deep components. Context in React is currently undocumented, but don't worry: it's a widely-used, safe part of React. (React Router uses context extensively.)\n\nContext is kind of weird, though. It's awkward to use and easy to abuse, which is probably why it's as-yet undocumented.\n\nFluxComponent treats context as an implementation detail, so you don't have to deal with it. Pass your Flux instance as a prop, and it will be added to the context of all its nested components.\n\nAdditionally, the immediate children of FluxComponent will be injected with a `flux` prop for easy access.\n\n```js\n<FluxComponent flux={flux}>\n  // Immediate children have flux prop\n  // flux has been added to context\n</FluxComponent>\n```\n\nIf flux is already part of the context, you can omit the flux prop on FluxComponent:\n\n```js\n<FluxComponent>\n  // Same as last time: immediate children have flux prop\n  // flux is already part of context, and remains so\n</FluxComponent>\n```\n\nSo if you pass a flux instance as a prop to a FluxComponent near the top of your app hierarchy, any FluxComponents further down the tree will automatically have access to it:\n\n```js\nReact.render(\n  <FluxComponent flux={flux}>\n    <App />\n  </FluxComponent>,\n  document.getElementById('app')\n)\n```\n\nPretty simple, right?\n\n## Subscribing to store updates\n\n**tl;dr** FluxComponent synchronizes with the state of your Flux stores and injects the state into its children as props.\n***\n\nStores are EventEmitters that emit change events whenever their state changes. To keep up to date, components must get the intial state, add an event listener, save a reference to the listener, and then remove the listener before unmounting to prevent memory leaks.\n\nThis sucks. And it's easy to mess up.\n\nFluxComponent hides all of these concerns behind a simple component interface. The prop `connectToStores` specifies which stores you want to stay in sync with. FluxComponents's immediate children will be injected with props corresponding to the state of those stores.\n\n```js\nclass OuterComponent extends React.Component {\n  render() {\n    return (\n      // Pass an array of store keys\n      <FluxComponent connectToStores={['storeA', 'storeB']}>\n        <InnerComponent />\n      </FluxComponent>\n    );\n  }\n}\n```\n\nIf `storeA` has state `{foo: 'bar'}` and `storeB` has state `{bar: 'baz'}`, then InnerComponent has props `foo=\"bar\"` and `bar=\"baz\"`. Whenever the stores change, so do the props.\n\n`connectToStores` will accept a single store key, an array of store keys, or a map of store keys to getter functions. A getter function is a function which takes a single parameter, the store, and returns an object of props to be injected into the children of FluxComponent. If a null is specified as a getter, the default getter is used instead, which simply returns the entire store state (like in the example above).\n\nSo, in just a few short lines, we can specify the initialization logic, update logic, and listening/unlistening logic for our component.\n\n```js\n// Pass an object of store keys mapped to getter functions\n<FluxComponent connectToStores={{\n  posts: store => ({\n    post: store.getPost(this.props.post.id),\n  }),\n  comments: store => ({\n    comments: store.getCommentsForPost(this.props.post.id),\n  })\n}}>\n  <InnerComponent />\n</FluxComponent>\n```\n\nIn this example, InnerComponent has props `post` and `comments`. If this auto-magic prop passing feels weird, or if you want direct control over rendering, you can pass a custom render function instead. Refer to the [FluxComponent](/flummox/docs/api/fluxcomponent) docs for more information.\n\n## Using fluxMixin\n\n**tl;dr** Just use FluxComponent. (Unless you don't want to. Up to you.) Read a longer explanation for [why FluxComponent is preferred](why-flux-component-is-better-than-flux-mixin).\n\n***\n\nFluxComponent is really just a wrapper around fluxMixin. (Seriously, check out the source.) But if you want to use fluxMixin directly, you can.\n\nLike FluxComponent, fluxMixin expects that the component you're mixing it into has access to a Flux instance via either a prop or context. It adds the Flux instance to the child context.\n\nUnlike FluxComponent, it does not inject props into its children. You can, however, access the instance with `this.flux`.\n\nfluxMixin adds a single method, `connectToStores()`. This is exactly like the `connectToStores` prop of FluxComponent. You can pass a single store key, an array of store keys, or a map of store keys to getter functions. In the single store key form, you can also pass a getter function as the second argument. (This form is not available to FluxComponent because props are single values.)\n\nfluxMixin does not inject store state as props into its children. Instead, it merges it into component state using `setState()`.\n\nWhen you call `connectToStores()`, it returns the current combined state of the stores (as specified by the getters). This is so you can use it within `getInitialState()`.\n\nHowever, there is a better way. fluxMixin is actually a function that returns a mixin object. Arguments passed to `fluxMixin()` are automatically sent to `connectToStores()` and used to set the initial state of the component.\n\n```js\n\nconst MyComponent = React.createClass({\n\n  // Remember, you can also use the single key or object forms\n  mixins[fluxMixin(['storeA', 'storeB'])],\n\n  ...\n});\n\n```\n\nIf `storeA` has state `{foo: 'bar'}` and `storeB` has state `{bar: 'baz'}`, then MyComponent has state `{foo: 'bar', bar: 'baz'}`. Whenever the stores change, so does MyComponent.\n"},{"path":"guides/why-flux-component-is-better-than-flux-mixin","content":"Why FluxComponent > fluxMixin\n=============================\n\nIn the [React integration guide](react-integration), I suggest that using [FluxComponent](/flummox/docs/api/fluxcomponent) is better than using [fluxMixin](/flummox/docs/api/fluxmixin), even though they do essentially the same thing. A few people have told me they like the mixin form more, so allow me to explain.\n\nMy argument can be broken down into three basic points. Note that these aren't my original ideas, nor are they unique to Flummox — they are the \"React Way\":\n\n- Declarative > imperative\n- Composition > inheritance\n- State is evil\n\nDeclarative > imperative\n------------------------\n\nThis is a no brainer. Remember the days before React, when you had to write one piece of code to render your application and another to update it? HAHAHAHA. That was awful. React showed us that expressing our views declaratively leads to clearer, more predictable, and less error-prone applications.\n\nYou might feel like fluxMixin and FluxComponent are equally declarative. They do have similar interfaces: a single argument/prop, that does (almost) the same thing. Still, as nice as fluxMixin's interface is, there's no beating a component in terms of clarity. A good rule of thumb in React is that everything that can be expressed as a component, should be.\n\n\nComposition > inheritance\n-------------------------\n\nReact has a very clear opinion on composition vs. inheritance: composition wins. Pretty much everything awesome about React — components, unidirectional data flow, the reconciliation process — derives from the fact that a React app is just a giant tree of components composed of other components.\n\nComponents make your code easy to reason about. If you stick to the basics of using components and props in your React app, you don't have to guess where data is coming from. The answer is always *from the owner*.\n\nHowever, when you use fluxMixin, you're introducing data into your component that comes not from the owner, but from an external source — your stores. (This is also true of FluxComponent, but to a lesser extent, as we'll see later.) This can easily lead to trouble.\n\nFor instance, here's a component that renders a single blog post, based on the id of the post.\n\n```js\nconst BlogPost = React.createClass({\n  mixins: [fluxMixin({\n    posts: (store, props) => ({\n      post: store.getPost(props.id),\n    })\n  })],\n\n  render() {\n    <article>\n      <h1>{this.state.post.title}</h1>\n      <div>{this.state.post.content}</div>\n    </article>\n  }\n});\n```\n\nCan you spot the problem? What happens when you want to re-use this same component to display a list of blog posts on your home page? Does it really make sense for each BlogPost component to separately retrieve its own post data from the store? Nope, not really.\n\nConsider that the owner component (BlogRoll, let's say) has to pass down an `id` prop in order for BlogPost to work properly. Where do you think BlogRoll is going to get that id from? The store, of course. Now you have BlogRoll *and* each of its children getting data from the store, each with their own event listeners, and each calling `setState()` every time the store changes. D'oh!\n\nA better approach is to separate the data fetching logic from the logic of rendering the post. Instead of having a prop `id`, BlogPost should have a prop `post`. It shouldn't concern itself with how the data is retrieved — that's the concern of the owner.\n\nAfter we rewrite BlogPost, it looks something like this:\n\n```js\nconst BlogPost = React.createClass({\n  render() {\n    <article>\n      <h1>{this.props.post.title}</h1>\n      <div>{this.props.post.content}</div>\n    </article>\n  }\n});\n```\n\nAnd its owner looks something like this:\n\n```js\nconst BlogPostPage = React.createClass({\n  mixins: [fluxMixin({\n    posts: (store, props) => ({\n      post: store.getPost(props.id),\n    })\n  })],\n\n  render() {\n    <div>\n      <SiteNavigation />\n      <MainContentArea>\n        <BlogPost post={this.state.post} />\n      </MainContentArea>\n      <SiteSidebar />\n      <SiteFooter />\n    </div>\n  }\n})\n```\n\n*For the sake of this example, let's just assume the `id` prop magically exists and is derived from the URL. In reality, we'd use something like React Router's [State mixin]( https://github.com/rackt/react-router/blob/master/docs/api/mixins/State.md).*\n\nThere's another problem, though. Every time the store changes, fluxMixin calls `setState()` on BlogPostPage, triggering a re-render of the *entire* component.\n\nWhich brings us to the final point...\n\nState is evil\n-------------\n\nOnce you've grokked the basics, this is perhaps the most important thing to know about React. To [think in React](http://facebook.github.io/react/blog/2013/11/05/thinking-in-react.html) is to find the minimal amount of state necessary to represent your app, and calculate everything based on that. This is because state is unpredictable. Props are, for the most part, derived from other props and state, but state can be anything. The more state in your application, the harder it is to reason about it. As much as possible, state in React should be an implementation detail — a necessary evil, not a crutch.\n\nOn an even more practical level, every time the state of a component changes, the entire component sub-tree is re-rendered. In our example from the previous section, BlogPostPage updates every time the `posts` store changes — including SiteNavigation, SiteSidebar, and SiteFooter, which don't need to re-render. Only BlogPost does. Imagine if you're listening to more than just one store. The problem is compounded.\n\nAlright, so we need to refactor once again so that fluxMixin is only updating what needs to be updated. We already learned that we shouldn't put the mixin inside BlogPost itself, because that makes the component less reusable. Our remaining option is to create a new component that wraps around BlogPost:\n\n```js\nconst BlogPostWrapper = React.createClass({\n  mixins: [fluxMixin({\n    posts: (store, props) => ({\n      post: store.getPost(props.id),\n    })\n  ]\n\n  render() {\n    <BlogPost post={this.state.post} />\n  }\n});\n```\n\nThis works. But it's kind of tedious, right? Imagine creating a wrapper like this for every single component that requires data from a store.\n\nWouldn't it be great if there were a shortcut for this pattern — a convenient way to update specific parts of your app, without triggering unnecessary renders?\n\nYep! It's called FluxComponent.\n\n```js\nclass BlogPostPage extends React.Component {\n  render() {\n    <div>\n      <SiteNavigation />\n      <MainContentArea>\n        <FluxComponent connectToStores={{\n          posts: store => ({\n            post: store.getPost(this.props.postId),\n          })\n        }}>\n          <BlogPost />\n        </FluxComponent>\n      </MainContentArea>\n      <SiteSidebar />\n      <SiteFooter />\n    </div>\n  }\n}\n```\n\nThe state fetched by `connectToStores()` is transferred to the children of FluxComponent. If this auto-magic prop passing feels weird, or if you want direct control over rendering, you can pass a custom render function instead:\n\n```js\nclass BlogPostPage React.Component {\n  render() {\n    <div>\n      <SiteNavigation />\n      <MainContentArea>\n        <FluxComponent\n          connectToStores={{\n            posts: store => ({\n              post: store.getPost(this.props.postId),\n            })\n          }}\n          render={storeState => {\n            // render whatever you want\n            return <BlogPost {...storeState} />;\n          }}\n        />\n      </MainContentArea>\n      <SiteSidebar />\n      <SiteFooter />\n    </div>\n  }\n}\n```\n\nDo what's right\n---------------\n\nIf I'm leaving you unconvinced, just do what you feel is right. I think components are generally preferable to mixins, but as with any rule, there are exceptions. For instance, [React Tween State](https://github.com/chenglou/react-tween-state) is a great project that wouldn't make sense as a component.\n\nEither way, both fluxMixin and FluxComponent are available for you to use, and both are pretty great :)\n\nIf you have any suggestions for how they could be improved, please let me know by submitting an issue.\n"}]