1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- function createStore(reducer) {
- let state = reducer(undefined, {}); //стартовая инициализация состояния, запуск редьюсера со state === undefined
- let cbs = []; //массив подписчиков
- const getState = () => state; //функция, возвращающая переменную из замыкания
- const subscribe = (cb) => (
- cbs.push(cb), //запоминаем подписчиков в массиве
- () => (cbs = cbs.filter((c) => c !== cb))
- ); //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
- const dispatch = (action) => {
- if (typeof action === "function") {
- //если action - не объект, а функция
- return action(dispatch, getState); //запускаем эту функцию и даем ей dispatch и getState для работы
- }
- const newState = reducer(state, action); //пробуем запустить редьюсер
- if (newState !== state) {
- //проверяем, смог ли редьюсер обработать action
- state = newState; //если смог, то обновляем state
- for (let cb of cbs) cb(); //и запускаем подписчиков
- }
- };
- return {
- getState, //добавление функции getState в результирующий объект
- dispatch,
- subscribe, //добавление subscribe в объект
- };
- }
- function countReducer(state = {count: 0}, {type}){
- if(type === "COUNT_INC"){
- return {
- count: state.count + 1
- }
- }
- if(type === "COUNT_DEC"){
- return {
- count: state.count - 1
- }
- }
- return state
- }
- function localStoreReducer (reducer, localStorageKey){
- function localStoredReducer (state, action){
- // Если state === undefined, то достать старый state из local storage
- if(state === undefined){
- try {
- return JSON.parse(localStorage[localStorageKey])
- } catch(e){}
-
- }
- const newState = reducer(state, action)
- // Сохранить newState в local storage
- localStorage[localStorageKey] = JSON.stringify(newState)
- return newState
- }
- return localStoredReducer
- }
- const store = createStore(localStoreReducer(countReducer, 'count'))
- store.subscribe(
- () => console.log(store.getState())
- )
- store.dispatch({type: "COUNT_INC"})
- store.dispatch({type: "COUNT_INC"})
- store.dispatch({type: "COUNT_DEC"})
|