Thinking about JavaScript apps with redux
Building apps is hard
Building a UI is hard
- Handling UI/other events
- Data persistence
- Rendering (when to re-render?)
- Maintaining and updating application state
Building a UI is hard
- Handling UI/other events
- Data persistence
- Rendering (when to re-render?)
- Maintaining and updating application state
Redux
Redux is a predictable state container for your JavaScript applications.
reduce
reduce<Acc> (xs: T[], fn : (Acc, T)) => Acc)
const sum = [1, 2, 3].reduce((acc = 0, i) => { return acc + i; }); console.log(sum); // 6
function sum(acc= 0, i) { return acc+ i; } const result = [1, 2, 3].reduce(sum); console.log(result); // 6
import { sum } from './reducers'; import { assert } from 'an-assertion-lib';
const expected = 8;
const actual = sum(7, 1);
assert(expected, actual);
// More tests here
export function sum(acc = 0, i) { return sum + i; }
reducers.js
reducers.test.js
Using reduce rocks
- Testable
- Declarative
- Predictable
The reducer function has some really nice qualities because it's pure
All these things make your application easier to think about
Guess what
reducer function === our application
function app(state = { todos: [] }, action) {
switch(action.type){
case 'ADD_TODO':
const todos = state.todos.concat([action.todo]);
return Object.assign(state, { todos });
default:
return state;
};
}
const actions = [
{ type: 'ADD_TODO', todo: 'Eat mor chkn' },
{ type: 'ADD_TODO', todo: 'Sleep off chkn' }
];
const result = actions.reduce(app);
console.log(result);
// { todos: ['Eat mor chkn', 'Sleep off chkn'] }
A redux-inspired example
This example does not actually use the redux library. It's purpose is to express one possible, DIY implementation of a redux-like architecture
DISCLAIMER
import { actions } from './actions'; // an Rx.Subject we can listen to
import { rootReducer } from './reducers'; // our application logic
// See this for documentation on the Rx.Observable.scan method
export const states = actions.scan(rootReducer); // emits each updated state
state.js
import { states } from './state';
export class App implements React.Component {
constructor() {
super();
this.state = { todos: [] }'
}
componentDidMount() {
// subscribe to state updates and trigger a re-render
states.subscribe(s => this.setState({ todos: s.todos}))
}
render() {
return <div>{this.state.todos.length}</div>;
}
};
app.jsx
Thinking about JavaScript apps with redux
By Calvin Belden
Thinking about JavaScript apps with redux
- 999