Components architecture

and

Redux

in

Polymer 2

at

Bob Bijvoet

Technical Lead Digital 2

Chapter Lead at BB (@Experience from jan 2017)

We're covering:

ING's component architecture

Intro into Redux

<Live code?>

We will touch on Polymer 2 specifics during the talk...

 

 

Why components?

  • Never reinvent the wheel
  • Share logic
  • Unified UX and design

Component architecture

  • Loose coupling
  • Easily shareable
  • Clear separation of concerns

Container

  • Are concerned with how things work.

  • May contain both presentational and container components.

  • Provide the data and configuration to presentational or other container components.

  • Are often stateful, as they tend to serve as data sources.

Presentational

  • Are concerned with how things look.
  • Don’t specify how the data is loaded or mutated.
  • Receive data via attributes
  • Are notifying container component of changes via event bubbling
  • Rarely have their own state (when they do, it’s UI state rather than data).

2 Types of Components

Inbox app

<inbox-list>
  <ajax-util result="{{result}}"/>
  <dom-repeat items="[[result]]">
</inbox-list>
<inbox-container>
  <ajax-util result="{{result}}"/>
  <inbox-list items="[[result]]"/>
</inbox-container>
<inbox-list items="[[result]]">
  <dom-repeat items="[[result]]"/>
</inbox-list>

Container component

Presentational component

<custom-element>

attrs

events

Presentational Component

<dom-repeat items={{items}}>
  <inbox-item on-click="deleteMessage([[index]])">
</dom-repeat>

 

deleteMessage() {items.splice(index, 1);}

 

deleteMessage() {
  this.dispatchEvent(
    new CustomEvent('delete-message', {
      detail: {id: this.item.id},
      bubbles: true,
      composed: true
}));
}

And emit events

<dom-repeat items=[[items]]>

Don't two-way bind

<inbox-container
  on-delete-message="deleteMessage"/>

deleteMessage() {
  //logic for deleting the message
}

Container component

It's the current standard in Digital 2

  • Docs are on The Guide
  • Examples are in Gitlab
  • In production already

Sharing state?

</>

A predictable state container for JavaScript apps.

Single source of truth

The state of your whole application is stored in an object tree within a single store.

 

 

State is read-only

The only way to mutate the state is to emit an action, an object describing what happened.

Changes are made with pure functions

To specify how the state tree is transformed by actions, you write pure reducers.

Pure function

  • Given the same input, will always return the same output.
  • Produces no side effects.
  • Relies on no external state.

Store

The single source of truth/place where all your application state lives

The UI subscribes to changes in the state

UI

//Inbox state
{
    messages:[...],
    selectedMessage:null,
    totalUnread:0
}

Actions

 

 Tells store that something happened and that the store should update itself in response.

Triggered by asynchronous interactions.

UI

//Fetch success
{
     type:'FETCH_MESSAGES_SUCCESS',
     items:response
}


//Open
{
     type:'OPEN_MESSAGE',
     item:{
        id:1
     }
}

//Remove
{
     type:'DELETE_MESSAGE',
     item:{
        id:1
     }
}

Reducers

 Responsible for mutating the store state when actions are dispatched.

Code that is run based on the action type.

UI

reducer(state, action) {
     switch (action.type) {
          case 'FETCH_MESSAGES_SUCCESS':
             //Set messages to XHR result
            return state;
          break;  
          case 'OPEN_MESSAGE':
            //Set selected message based on action.id 
            //Set message to unread based on action.id
            return state;
          break;  

          case 'REMOVE_MESSAGE':
             //Remove message based on action.id 
            return state;

          break;
              
     }
   return state;
     
}

//Always return a new object

return Object.assign({}, state, {/* state modifications */})

//It's a new assignment, thus no comparison needed

</>

Testing

Debugging

 

Benefits

 

  • Single place for app logic
  • Clear list of actions
  • Powerful debugging
  • Easily testable
  • Async state representation

Live coding...

If there's time left, I'll add the unread action!

Goodies

Thanks

Questions?

Redux and Polymer 2

By Bob Bijvoet

Redux and Polymer 2

  • 3,476