npm i github:unicornshade/redux-store
new Store(reducer, initialState)
reducer — чистая функция, которая принимает предыдущий state и action, а возвращает новый state.
initialState — объект, содержащий начальное состояние store.
Возвращает текущее состояние store.
store.getState()
Вызывает reducer с указанным action.
store.dispatch(action)
action — объект с указанием типа действия и полезной нагрузкой
{
type: 'Action',
value: 'some value'
}
Позволяет подписаться на изменение state.
store.subscribe(subscriber)
subscriber — функция-подписчик, вызывающаяся при изменении state.
store.subscribe(state => console.log(state))
Добавляет middleware.
store.use(middleware)
middleware — позволяет расширить логику между отправкой action и reducer'ом, принимающим этот action.
const logger = store => next => action => {
console.log('dispatching', action)
let result = next(action)
console.log('next state', store.getState())
return result
}
store.use(logger)
const initialState = {
counter: 0,
name: ''
}
const reducer = (state, action) => {
switch (action.type) {
case 'INCREMENT': {
return { ...state, counter: ++state.counter }
}
case 'DECREMENT': {
return { ...state, counter: --state.counter }
}
case 'CHANGE_NAME': {
return { ...state, name: action.name }
}
}
}
// Actions
const increment = () => ({ type: 'INCREMENT' })
const decrement = () => ({ type: 'DECREMENT' })
const changeName = name => ({type: 'CHANGE_NAME', name })
// Store initialization
const store = new Store(reducer, initialState)
// state = { counter: 0, name: '' }
store.dispatch(increment())
store.dispatch(increment())
// state = { counter: 2, name: '' }
store.dispatch(decrement())
// state = { counter: 1, name: '' }
store.dispatch(changeName('Fake Name'))
// state = { counter: 1, name: 'Fake Name' }
Middleware, который позволяет написать action, возвращающий функцию с объектом action. Используется для того, чтобы отсрочить выполнение dispatch, например для асинхронных операций.
store.use(useThunk())
const fetchData = dispatch => {
fetch('host/api/endpoint')
.then(res => res.json())
.then(data => dispatch(data))
}
Для View реализован класс Component
, у которого есть метод render
new Component(element)
element — DOM элемент
Чтобы подключить store к компоненту используется функция:
connectStore(store, Component)
store — экземпляр Store
Component — класс, унаследованный от Component
// store использован из предыдущего примера
// { counter: 0 }
class Counter extends Component {
constructor(element) {
super(element)
this.elem.addEventListener('click', () => {
this.dispatch(increment())
})
}
render({ counter }) {
return `<span>${counter}</span>`
}
}
const WithStoreCounter = connectStore(store, Counter)
const counterElem = document.getElementById('counter')
new WithStoreCounter(counterElem)
store.dispatch(increment())
store.dispatch(increment())
store.dispatch(increment())
Результирующий html
<!-- ... -->
<div id="counter">
<span>3</span>
</div>
<!-- ... -->
Данный пример доступен в папке example