using redux with polymer
TRANSCRIPT
Collaborne
Using Redux with PolymerRonny Roeller (CTO Collaborne)
Collaborne
Data within app needs to be in sync (focus of presentation)
Data between users needs to be in sync
What’s the problem?
Collaborne
Good: Frontend is heavily decentralized via its components (Polymer)
Data binding for centralization Problem: every component can mutate the state
(+ asynchronicity) Very common issue: Facebook private messages
counter led to Flux pattern (not a technology) – see talk
Learn more: “Polymer loves Redux” (Medium)
Components vs. Centralization
Collaborne
Most widely used Flux implementation Three principles
1. Single source of truth (app state is stored in one object)
2. State is read only3. Changes are made with pure functions
Learn more: Dan’s introduction and
advanced course
What’s Redux?
Collaborne
UI dispatches actions:{ type: 'SET_TODO_STATE', done: true}
Reducers listens to actions and create new state:reducer(state, action) { if (action.type === 'SET_TODO_STATE') { return { status: action.done ? 'done' : 'open' };...
Actions & Reducers
Collaborne
How does this help?
* Source: Facebook
Collaborne
Dev Tools extension (Chrome) Time travel / undo Actions State object
Demo
Collaborne
Polymer-redux is a super thin Polymer binding library
Bind a property:const ReduxBehavior = PolymerRedux(MyReduxStore);Polymer({ is: "my-element", properties: { todos: { type: Array, statePath: "todos.all", readOnly: true }, }, behaviors: [ ReduxBehavior ]
Connecting Polymer + Redux 1/2
Collaborne
Dispatch an action:this.dispatch({ type: 'TOGGLE_TODO', id: id});
Learn more: “Polymer loves Redux” (Medium)
Connecting Polymer + Redux 2/2
Collaborne
UI components shouldn’t know about state shape Access derived data (look up table + current
person ID) without unnecessary computation Selectors calculate & cache:
const personSelector = Reselect.createSelector( state => state.ui.person.personId, state => state.data.people.byId (personId, byId) => byId[personId]);
Learn more: “Selectors in polymer-redux” (Medium)
Selectors
Collaborne
Reducers should be composed (pure functions):reducer(state, action) { return { users: uiUsersReducer(state.users, action), groups: uiGroupsReducer(state.groups, action) }};
• Split UI components from Redux• Split Redux code by data/ui• Match component structure with store shapeLearn more: “Organize Large Redux Projects”
(Medium)
Code organization
Collaborne
Generally Polymer and Redux work very well together
Be careful where Polymer expects mutations (instead of a new object), e.g. lists might flicker
Translate between Redux object and Polymer propertyvar splices = Polymer.ArraySplice.calculateSplices( reduxItems, polymerItems);polymerItems.length = 0;polymerItems.push(...reduxItems);this.notifySplices(‘polymerItems’, splices);
Learn more: “Stop Polymer lists from flickering”
(Medium)
Polymer vs. Redux clashes
Collaborne
Questions?
@ronnyroeller
Learn more on our Engineering Blog