123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- {
- function colorReducer(state, {type, value}) {
- if (state === undefined) {
- return {
- red: 0,
- green: 0,
- blue: 0
- }
- }
- if (type === 'COLOR_RED' && typeof value === 'number' && value >= 0 && value <= 255) {
- return {
- ...state,
- red: value
- }
- }
- if (type === 'COLOR_GREEN' && typeof value === 'number' && value >= 0 && value <= 255) {
- return {
- ...state,
- green: value
- }
- }
- if (type === 'COLOR_BLUE' && typeof value === 'number' && value >= 0 && value <= 255) {
- return {
- ...state,
- blue: value
- }
- }
- return state
- }
- 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 => {
- const newState = reducer(state, action) //пробуем запустить редьюсер
- if (newState !== state) { //проверяем, смог ли редьюсер обработать action
- state = newState //если смог, то обновляем state
- for (let cb of cbs) cb() //и запускаем подписчиков
- }
- }
- return {
- getState, //добавление функции getState в результирующий объект
- dispatch,
- subscribe //добавление subscribe в объект
- }
- }
- let store = createStore(colorReducer);
- console.log(store.getState())
- console.log(store.dispatch("COLOR_RED", 50))
- console.log(store.getState())
- store.subscribe(() => console.log(store.getState()))
- store.dispatch("COLOR_RED", 60)
- store.dispatch("COLOR_BLUE", 600);
- const actionColorRed = value => ({type: "COLOR_RED", value});
- const actionColorGreen = value => ({type: "COLOR_GREEN", value});
- const actionColorBlue = value => ({type: "COLOR_BLUE", value});
- store.dispatch(actionColorBlue(100))
- store.subscribe(() => {
- const {red, green, blue} = store.getState()
- document.body.style.backgroundColor = `rgb(${red}, ${green}, ${blue})`
- })
- store.dispatch(actionColorGreen(100))
- store.dispatch(actionColorGreen(200))
- const redInput = document.createElement('input')
- redInput.type = 'number'
- redInput.min = 0;
- redInput.max = 255
- redInput.oninput = () => store.dispatch(actionColorRed(+redInput.value))
- document.body.append(redInput)
- const greenInput = document.createElement('input')
- greenInput.type = 'number'
- greenInput.min = 0;
- greenInput.max = 255
- greenInput.oninput = () => store.dispatch(actionColorGreen(+greenInput.value))
- document.body.append(greenInput)
- store.subscribe(() => redInput.value = store.getState().red)
- store.dispatch(actionColorRed(100))
- const inputColor = document.createElement('input')
- inputColor.type = 'color'
- inputColor.oninput = () => console.log(inputColor.value)
- document.body.append(inputColor)
- inputColor.oninput = () => {
- const hex = inputColor.value
- const red = parseInt(hex.slice(1, 3), 16)
- const green = parseInt(hex.slice(3, 5), 16)
- const blue = parseInt(hex.slice(5, 7), 16)
- store.dispatch(actionColorRed(red))
- store.dispatch(actionColorGreen(green))
- store.dispatch(actionColorBlue(blue))
- console.log(red, green, blue)
- }
- store.subscribe(() => {
- const {red, green, blue} = store.getState()
- const colorToHex = value => (value < 16 ? '0' : '') + value.toString(16)
- inputColor.value = `#${colorToHex(red)}${colorToHex(green)}${colorToHex(blue)}`
- })
- store.dispatch(actionColorRed(0))
- store.dispatch(actionColorGreen(0))
- store.dispatch(actionColorBlue(0))
- } */
|