Создание store и его изменение (dispatch). Подписка на изменения (subscribe), Использование dispatch с дополнительными аргументами (payload). Action Creators.
Содержание
Создание store и его изменение (dispatch)
import { createStore } from 'redux';
const reducer = (state = 0, action) => {
switch(action.type) {
case 'INC':
return state + 1;
case 'DEC':
return state - 1;
default:
return state;
}
}
const store = createStore(reducer);
console.log(store.getState()); // 0
store.dispatch({type: 'INC'});
console.log(store.getState()); // 1
store.dispatch({type: 'INC'});
console.log(store.getState()); // 2
store.dispatch({type: 'DEC'});
console.log(store.getState()); // 1
store.dispatch({type: 'ABRACARBA'});
console.log(store.getState()); // 1
Reducer всегда должен быть «чистой функцией», т.е.:
- Возвращаемое значение зависит только от аргументов. Т.е. для одних и тех же входящих аргументов всегда будет одинаковый результат.
- Нет побочных эффектов, т.е. не изменяет лексическое окружение (scope), DOM, БД , localStorage и т.д.
Подписка на изменение store (subscribe)
import { createStore } from 'redux';
const reducer = (state = 0, action) => {
switch(action.type) {
case 'INC':
return state + 1;
case 'DEC':
return state - 1;
default:
return state;
}
}
const store = createStore(reducer);
store.subscribe(() => {
console.log(store.getState());
})
/*
subscribe срабатывает на возможное изменение store,
при вызове метода dispatch.
При {type: 'ABRACARBA'} изменение store не происходит,
но subscribe всё равно срабатывает
*/
store.dispatch({type: 'INC'}); // 1
store.dispatch({type: 'DEC'}); // 0
store.dispatch({type: 'ABRACARBA'}); // 0
Использование dispatch с дополнительными аргументами (payload)
import { createStore } from 'redux';
const reducer = (state = 0, action) => {
switch(action.type) {
case 'ADD_100':
return state + action.payload;
case 'SUM':
return action.v1 + action.v2;
default:
return state;
}
}
const store = createStore(reducer);
store.subscribe(() => {
console.log(store.getState());
})
store.dispatch({
type: 'ADD_100',
payload: 100
}); // 100
store.dispatch({
type: 'SUM',
v1: 100,
v2: 200
}); // 300
Применение Action Creators
Action Creators помогают повторно использовать код, чем упрощают его и снижают вероятность ошибок. Сделаем AC для действия ‘SUM’
// Было
store.dispatch({
type: 'SUM',
v1: 100,
v2: 200
}); // 300
// Стало
const sum = (v1, v2) => ({type: 'SUM', v1: v1, v2: v2});
store.dispatch(sum(100, 200));
Упрощаем код через деструктурирование
import { createStore } from 'redux';
const reducer = (state = 0, action) => {
switch(action.type) {
case 'SUM':
return action.v1 + action.v2;
default:
return state;
}
}
const store = createStore(reducer);
const { dispatch, subscribe } = store; // извлекаем функции из объекта store
subscribe(() => { // применяем subscribe
console.log(store.getState());
})
const sum = (v1, v2) => ({type: 'SUM', v1: v1, v2: v2});
dispatch(sum(100, 200)); // применяем dispatch