Skip to content

Instantly share code, notes, and snippets.

@devinivy
Last active January 27, 2016 19:59
Show Gist options
  • Save devinivy/ad4c2a7bef1c40fb2343 to your computer and use it in GitHub Desktop.
Save devinivy/ad4c2a7bef1c40fb2343 to your computer and use it in GitHub Desktop.
Polymer with Reflux

Polymer with Reflux

Implementation

Ties together Polymer and Reflux

Is a demo of using Polymer with Reflux via funk

The Pieces

These are thoughts pre-funk!

Views

  • Views are Polymer v1 components.
  • They access stores via the StateBehavior.
  • Ideally all properties of the component are derived from this.state. Low-level components such as list items might be "stateless" (in the context of the app) and just render derived state that is handed to them through downward binding.
  • Components may not manipulate this.state or any of its subproperties (stores) directly. This will be enforced by discipline, but could probably be detected.

Actions

  • Actions are grouped into Polymer behaviors.
  • They look like simple method calls with an arbitrary number of arguments.
  • The views respond to user interaction by calling actions.
  • Actions are fire-and-forget. They will likely result in changes to the stores, and may react to those as needed. Consider how this affects toasts being fired, say, on an API error. This said, some think that asynchronous actions may return promises for their completion. I don't think reflux itself supports this, though it does support "children" actions...
  • Actions may have "children" actions– for example, an action that makes an API request might have a success and failure sub-action.

Stores

  • Stores are Polymer v1 components that are included into the app once.
  • They listen for actions.
  • They also listen to changes in other stores by standard Polymer observers of 'state.someStore.etc.etc'. It's preferrable to listen to actions over changes to other stores.
  • Stores react to actions and changes in other stores, then manipulate some self-contained piece of app-state (e.g. 'state.currentAvatar').
  • They are limited to change some specific piece of app-state. They are solely responsible for that piece of app-state. This could be enforced by creating methods that mirror set(), push(), etc. and prepend 'state.someSpecificPieceOfAppState' to the first argument.
  • "Fewer stores are better" -@sethwklein

Now the flow of the app is unidirectional, View--> Action -->Stores -->Views.

Example

A user clicks a little heart button. The view for that button calls favoritePost(postId). The favoritePost() action makes an API request that will later trigger a favoritePostSucceded(postId) or favoritePostFailed(postId) action some time in the future. In the meantime, though, the <post-list> store was listening for the favoritePost(postId) action, and optimistically incremented the favoritesCount field on the post in its list with id postId. Later the favoritePostFailed(postId) action is fired because the API was down. The <post-list> store was listening for that action, and reacts by decrementing the favoritesCount for post with id postId. While all these changes were taking place, the number below the little heart button displayed "0" then "1" then "0" again, because sadly things just didn't work out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment