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
*/
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
*/
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'
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;
}
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));
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
The only way to change the state is to emit an action, an object describing what happened.
To specify how the state tree is transformed by actions, you write pure reducers.
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);
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' });