Ties together Polymer and Reflux
Is a demo of using Polymer with Reflux via funk
These are thoughts pre-funk!
- 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 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 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
.
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.