Эта страница переведена PageTurner AI (бета). Не одобрена официально проектом. Нашли ошибку? Сообщить о проблеме →
Основные концепции
Представьте, что состояние вашего приложения описывается простым объектом. Например, состояние приложения для списка дел может выглядеть так:
{
todos: [{
text: 'Eat food',
completed: true
}, {
text: 'Exercise',
completed: false
}],
visibilityFilter: 'SHOW_COMPLETED'
}
Этот объект похож на "модель", за исключением того, что в нём нет сеттеров. Это предотвращает произвольное изменение состояния разными частями кода, что может приводить к трудно воспроизводимым ошибкам.
Чтобы изменить состояние, вам нужно отправить действие. Действие — это простой JavaScript-объект (обратите внимание, что мы не используем никакой магии?), который описывает произошедшее событие. Вот несколько примеров действий:
{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }
Требование описывать каждое изменение через действие позволяет чётко понимать, что происходит в приложении. Если что-то изменилось, мы знаем почему. Действия похожи на хлебные крошки, оставляемые событиями. Наконец, чтобы связать состояние и действия, мы пишем функцию под названием редьюсер. Опять же, ничего магического — это просто функция, которая принимает состояние и действие как аргументы и возвращает следующее состояние приложения. Писать такую функцию для большого приложения было бы сложно, поэтому мы создаём небольшие функции, управляющие частями состояния:
function visibilityFilter(state = 'SHOW_ALL', action) {
if (action.type === 'SET_VISIBILITY_FILTER') {
return action.filter
} else {
return state
}
}
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return state.concat([{ text: action.text, completed: false }])
case 'TOGGLE_TODO':
return state.map((todo, index) =>
action.index === index
? { text: todo.text, completed: !todo.completed }
: todo
)
default:
return state
}
}
И пишем ещё один редьюсер, который управляет полным состоянием нашего приложения, вызывая эти два редьюсера для соответствующих ключей состояния:
function todoApp(state = {}, action) {
return {
todos: todos(state.todos, action),
visibilityFilter: visibilityFilter(state.visibilityFilter, action)
}
}
В этом и заключается основная идея Redux. Обратите внимание, что мы не использовали никаких API Redux. Библиотека предоставляет несколько вспомогательных инструментов для реализации этого паттерна, но главная идея в том, что вы описываете, как ваше состояние обновляется в ответ на объекты действий, при этом 90% вашего кода — это обычный JavaScript без использования самого Redux, его API или какой-либо магии.