test.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. function createStore(reducer) {
  2. let state = reducer(undefined, {}); //стартовая инициализация состояния, запуск редьюсера со state === undefined
  3. let cbs = []; //массив подписчиков
  4. const getState = () => state; //функция, возвращающая переменную из замыкания
  5. const subscribe = (cb) => (
  6. cbs.push(cb), //запоминаем подписчиков в массиве
  7. () => (cbs = cbs.filter((c) => c !== cb))
  8. ); //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
  9. const dispatch = (action) => {
  10. if (typeof action === "function") {
  11. //если action - не объект, а функция
  12. return action(dispatch, getState); //запускаем эту функцию и даем ей dispatch и getState для работы
  13. }
  14. const newState = reducer(state, action); //пробуем запустить редьюсер
  15. if (newState !== state) {
  16. //проверяем, смог ли редьюсер обработать action
  17. state = newState; //если смог, то обновляем state
  18. for (let cb of cbs) cb(); //и запускаем подписчиков
  19. }
  20. };
  21. return {
  22. getState, //добавление функции getState в результирующий объект
  23. dispatch,
  24. subscribe, //добавление subscribe в объект
  25. };
  26. }
  27. function countReducer(state = {count: 0}, {type}){
  28. if(type === "COUNT_INC"){
  29. return {
  30. count: state.count + 1
  31. }
  32. }
  33. if(type === "COUNT_DEC"){
  34. return {
  35. count: state.count - 1
  36. }
  37. }
  38. return state
  39. }
  40. function localStoreReducer (reducer, localStorageKey){
  41. function localStoredReducer (state, action){
  42. // Если state === undefined, то достать старый state из local storage
  43. if(state === undefined){
  44. try {
  45. return JSON.parse(localStorage[localStorageKey])
  46. } catch(e){}
  47. }
  48. const newState = reducer(state, action)
  49. // Сохранить newState в local storage
  50. localStorage[localStorageKey] = JSON.stringify(newState)
  51. return newState
  52. }
  53. return localStoredReducer
  54. }
  55. const store = createStore(localStoreReducer(countReducer, 'count'))
  56. store.subscribe(
  57. () => console.log(store.getState())
  58. )
  59. store.dispatch({type: "COUNT_INC"})
  60. store.dispatch({type: "COUNT_INC"})
  61. store.dispatch({type: "COUNT_DEC"})