
Pure Functions

function add(a, b) {
return a + b;
}
function capitalize(str) {
return str.slice(0, 1)
.toUpperCase()
.concat(str.slice(1));
}
/*
built-in pure functions:
filter, map, reduce, some, every, slice, concat
*/
Pure functions
let result = null;
function add(a, b) {
result = a + b;
return result;
}
function request(url) {
return fetch(url);
}
function setName(obj, name) {
obj.name = name;
return obj;
}
/*
built-in impure functions:
sort, reverse, push, splice, shift, unshift
*/
Impure functions
Immutability
const obj = { name: 'John' };
const a = obj;
const b = obj;
b.name = 'James';
console.log(b.name) // 'James'
console.log(obj.name) // 'James'
console.log(a.name) // 'James'
Javascript has mutable objects by default
let obj = { name: 'John', age: 20 };
const b = obj;
obj = { ...obj, name: 'James' };
console.log(obj) // { name: 'James', age: 20 }
console.log(b) // { name: 'John', age: 20 }const state = {
users: [
{ name: 'admin', isAdmin: true },
],
movies: [],
};
getUsers()
.then((users) => state.users.push(...users))
.catch(err => console.log(err));
function removeMovie(movieId) {
const index = state.movies.findIndex(movie => movie.id === movieId);
state.movies.splice(index, 1);
}
function removeAdmin(userName) {
const user = state.users.find(user => user.name === userName);
user.isAdmin = false;
}
Mutable style
class Store {
constructor(state) {
this.state = state;
}
getState() {
return this.state;
}
setState(newState) {
this.state = newState;
}
}
const store = new State({
users: [
{ name: 'admin', isAdmin: true },
],
movies: [],
});
getUsers()
.then((users) => {
const newState = {
...store.getState(),
users,
}
store.setState(newState);
})
.catch(err => console.log(err));
Immutable style
function removeMovie(movieId) {
const state = store.getState();
const newState = {
...state,
movies: state.movies.filter(
movie => movie.id !== movieId
)
};
state.setState(newState);
}
function removeAdmin(userName) {
const state = store.getState();
const newState = {
...state,
users: state.users.map(user => {
if (user.name === userName) {
return { ...user, { isAdmin: false } };
}
return user;
})
}
store.setState(newState);
}

Flux is a pattern for managing data flow in your application. The most important concept is that data flows in one direction.
Flux parts:
Dispatcher
Store
Action
View






Redux is a predictable state container for JavaScript apps.
Redux main principles
- Read-only state
The only way to change 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.
- Single source of truth
The state of your whole application is stored in an object tree within a single store.
Reducer changes state based on dispatched action and current state
reduce((currentState, action) => {
// logic
}, initialState);
npm install reduximport { createStore } from 'redux';
const reducer = (state = 0, action) => {
if (action.type === 'INCREMENT') {
return state + 1;
} else if (action.type === 'DECREMENT') {
return state - 1;
}
return state;
};
const store = createStore(reducer);
// actions
const inc = { type: 'INCREMENT' };
const dec = { type: 'DECREMENT' };
store.dispatch(inc);
store.dispatch(inc);
store.dispatch(inc);
store.dispatch(dec);
store.getState(); // outputs 2
const ubsubscribe = store.subscribe(() => {
const currentState = store.getState();
console.log(currentState);
});
store.dispatch(inc);
store.dispatch(inc);
store.dispatch(inc);
unsubscribe();
store.dispatch(inc);
store.dispatch(inc);
store.dispatch(inc);
Middlewares
Middleware provides a third-party extension point between dispatching an action, and the moment it reaches the reducer. People use Redux middleware for logging, crash reporting, talking to an asynchronous API, routing, and more.
import { createStore, applyMiddleware } from 'redux';
import logger from 'redux-logger';
const reducer = (state = 0, action) => {
if (action.type === 'INCREMENT') {
return state + 1;
} else if (action.type === 'DECREMENT') {
return state - 1;
}
return state;
};
const store = createStore(reducer, applyMiddleware(logger));
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'DECREMENT' })

const mymiddleware = store => next => action => {
console.log('My middleware in action!');
return next(action);
}import { createStore, applyMiddleware } from 'redux';
import logger from 'redux-logger';
const reducer = (state = 0, action) => {
if (action.type === 'INCREMENT') {
return state + 1;
} else if (action.type === 'DECREMENT') {
return state - 1;
}
return state;
};
const mymiddleware = store => next => action => {
console.log('My middleware in action!');
return next(action);
}
const store = createStore(reducer, applyMiddleware(mymiddleware, logger));
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'DECREMENT' });

References
redux lecture
By Nikita Rudy
redux lecture
- 527