Кожного разу, коли відбувається зміна стану, Реакт будує новий віртуальни DOM для всього, що знаходиться нижче в ієрархії
Функції, котрі описують дію. Використовуватимуться в UI
function addItem(data) {
Dispatcher.dispatch({
type: ADD_ITEM,
data
})
}
Найпростіший AC абстаргує нас від диспетчера, в мабутньому може бути ускладнений
Хороша практика: використання констант для опису типів подій(в цьому випадку ADD_ITEM)
В класичному Flux коммунікації з API виносяться в
Action Creators
function loadItem(id) {
Dispatcher.dispatch({
type: LOAD_ITEM_START,
data: { id }
})
$.get(`/api/items/${id}`)
.done((response) => {
Dispatcher.dispatch({
type: LOAD_ITEM_SUCCESS,
data: { response }
})
})
.fail((error) => {
Dispatcher.dispatch({
type: LOAD_ITEM_FAIL,
data: { id, error }
})
})
}
Найпростіший Store відповідає за роботу з данними
і повідомляє про їх зміни
class AbstractStore extends EventEmitter {
constructor() {
super()
this.__items = []
}
emitChange() {
this.emit(STORE_CHANGE_EVENT)
}
addChangeListener(callback) {
this.on(STORE_CHANGE_EVENT, callback)
}
removeChangeListener(callback) {
this.removeListener(STORE_CHANGE_EVENT, callback)
}
getAll() {
return this.__items
}
add(item) {
this.__items.push(item)
}
}
Деякі Store Мусять реагувати на події
class ItemStore extends AbstractStore {
constructor() {
super()
this.dispatchToken = Dispatcher.register((action) => {
const { data, type } = action
switch (type) {
case ADD_ITEM:
this.add(data)
this.emitChange()
break;
}
})
}
}
В такий Store завжди потраплятимуть всі події з диспетчеру, він сам муисть визначити на які реагувати, а які ігнорувати
<Router history = {createBrowserHistory()}>
<Route path = "/" component = {App} onEnter = {checkAuth}>
<IndexRoute component = {ArticleList} />
<Route path = "new" component = {NewArticle} />
<Route path = "/:id" component = {ArticlePage} />
</Route>
<Route path="*" component = {NotFound} />
</Router>