acdlite/flummox

View on GitHub
docs/dist/flummox/data/docs/api/store.json

Summary

Maintainability
Test Coverage
{"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"}