Introduction to Redux

using Angular 2

by Gerard Sans (@gerardsans)

Google Developer Expert

Master of Ceremonies

International Speaker

Angular 2 Trainer

Community Leader

800

500

AngularConnect - Sept 27-28th

@AngularConnect

Redux

Dan Abramov

@gaearon

Main Features

  • Unidirectional data flow
  • Single Immutable State
  • Changes made only by reducers

Unidirectional data flow

Angular 2

Components Tree

source: blog

Components Tree

<root>
  <add-todo>
    <input><button>Add todo</button>
  </add-todo>
  <todo-list>
    <ul>
      <todo id="0" completed="false"><li>buy milk</li></todo>
    </ul>
  </todo-list>
  <filters>
    Show: <filter-link><a>All</a><filter-link> ... 
  </filters>
</root>

Adding a new Todo

  • Component subscribes to store
  • User dispatches action
  • Store executes rootReducer
  • Update View

Subscribe

@Component({
  template: 
      `<todo *ngFor="#todo of todos">{{todo.text}}</todo>`
})

export class TodoList implements OnDestroy {
  constructor(@Inject('AppStore') private appStore: AppStore){
    this.unsubscribe = this.appStore.subscribe(() => {
      let state = this.appStore.getState();
      this.todos = state.todos;
    });
  }
  private ngOnDestroy(){
    this.unsubscribe();
  }
}

Actions

// add new todo item
{
  type: ADD_TODO,
  id: 1,
  text: "learn redux",
  completed: false
}

rootReducer

const initialState = {
  todos: [],
  currentFilter: 'SHOW_ALL'
}

export function rootReducer(state = initialState, action){
  switch (action.type) {
    case TodoActions.ADD_TODO: 
      return { 
        todos: state.todos.concat({ 
          id: action.id,
          text: action.text,
          completed: action.completed }),
        currentFilter: state.currentFilter 
      }
    default: return state;
  }
}

New State

{
  todos: [{
    id: 1,
    text: "learn redux",
    completed: false
  }],
  currentFilter: 'SHOW_ALL'
}

Dumb Todo Component

@Component({
  inputs: ['completed', 'id'],
  template: `
    <li (click)="onTodoClick(id)"
      [style.textDecoration]="completed?'line-through':'none'">
      <ng-content></ng-content>
    </li>`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class Todo { 
  constructor(
    @Inject('AppStore') private appStore: AppStore, 
    private todoActions: TodoActions){ }

  private onTodoClick(id){
    this.appStore.dispatch(this.todoActions.toggleTodo(id));
  }
}

Libraries

  • Built on top of Redux
  • Compatible w/ DevTools
  • Built on top of RxJS 5
  • Leverages Angular 2

Why use Redux?

Main Benefits

  • Simplified Development
  • Avoids complex dependencies
  • Performance

Bedankt!