Redux & Angular2
Part 1
Redux in short
"Redux is a predictable state container for JavaScript apps.
It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time traveling debugger."
from reactjs/redux repo
Store
Store will store your application state.
The Store is king of the "database" of client side. it's the 'single source of truth' and can be queried from any place of the application.
snapshot of store at any point will supply a complete representation of relevant application state.
Reducers
Pure functions that takes 2 params:
- Current state
- Action (with optional payload
Reducer function will return a new state object
// Action interface
export interface Action {
type: string;
payload?: any;
}
Centralized, Immutable State
Dispatched Action Pipeline
Code time
EventReducer
- cd src/app
mkdir reducers && cd reducers
touch events.reducer.ts
- import Action:
- Define Actions constants (export for future import):
import { Action } from '@ngrx/store';
export const GET_EVENTS = 'GET_EVENTS';
export const GET_EVENTS_SUCCESS = 'GET_EVENTS_SUCCESS';
export const ADD_EVENTS = 'ADD_EVENTS';
EventReducer
- Define our Events State interface:
- Define the initial state params:
const initialState: EventsState = {
events: [],
loading: false,
...
};
export interface EventsState {
events: any;
loading: boolean;
...
}
EventReducer
- Define the reducer and add logic:
export const eventsReducer = (state = initialState, action: Action): EventsState => {
switch (action.type) {
case GET_EVENTS:
return Object.assign({}, state, {
loading: true
});
case GET_EVENTS_SUCCESS:
return Object.assign({}, state, {
loading: false
});
case ADD_EVENTS:
return Object.assign({}, state, {
events: state.events.concat(action.payload)
});
....
default:
return state;
}
}
Register the store in app bootstrap
- Import 'store' and 'store-devtools':
- Open src/main.ts and add providers for the store and for redux devtools:
bootstrap(AppComponent, [
...
provideStore({ events: eventsReducer }),
instrumentStore(),
...
]);
import { provideStore } from '@ngrx/store';
import { instrumentStore } from '@ngrx/store-devtools';
Dispatch from component
- Import Store and actions constants from reducer:
- Modify constructor to include store:
- Dispatch action from a function:
import { Store } from '@ngrx/store';
import { GET_EVENTS, GET_EVENTS_SUCCESS, ADD_EVENTS } from '../reducers/events.reducer';
constructor(public store: Store<any>, ...)
getEvents(start: number, end: number) {
this.store.dispatch({ type: GET_EVENTS });
this.eventsService.getEvents(start, end)
.subscribe(res => {
this.store.dispatch({ type: GET_EVENTS_SUCCESS });
this.store.dispatch({ type: ADD_EVENTS, payload: res.data.map(event => new EventModel(event)) });
});
}
Getting data from Store in a component
- Use the 'select' function on the store
- Get Events state data
- Subscribe for changes
- Bind data to the class members for view usage
constructor(public store: Store<any>, ...) {
store.select(s => s.events).subscribe(eventsState => {
this.events = eventsState.events;
this.loading = eventsState.loading;
...
});
}
Redux DevTools
Open installed chrome extension 'Redux Devtools' and see the actions goes in.
Homework
- Get the static template of event route from '_templates/event.html' and get it into the app
- Bind the data
- Make use of existing components for reuse
- Make new components if needed
- Implement 'CHANGE_RSVP_STATE' action function in eventsReducer and dispatch this action from 'EventRsvpToggleBtnComponent'
- Play around with 'redux devtools' chrome extension to test the redux implementation you added
Need help?
https://gitter.im/dvh91/kmeetups
ngrx-store-01
By Dvir Hazout
ngrx-store-01
- 833