Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как reducer связан со store?
Reducer и Store работают вместе в архитектуре управления состоянием (Redux, Vuex, Pinia и т.д.). Это паттерн для централизованного хранения и управления состоянием приложения.
Что такое Store?
Store — это единственный источник истины (single source of truth), который хранит всё состояние приложения:
interface AppState {
user: {
id: string;
name: string;
email: string;
};
theme: 'light' | 'dark';
notifications: Notification[];
}
const initialState: AppState = {
user: null,
theme: 'light',
notifications: []
};
// Store хранит это состояние
const store = createStore(initialState);
Что такое Reducer?
Reducer — это чистая функция, которая получает текущее состояние и действие (action), затем возвращает новое состояние:
type Action =
| { type: 'SET_USER'; payload: User }
| { type: 'TOGGLE_THEME' }
| { type: 'ADD_NOTIFICATION'; payload: Notification };
function reducer(state: AppState, action: Action): AppState {
switch (action.type) {
case 'SET_USER':
return { ...state, user: action.payload };
case 'TOGGLE_THEME':
return {
...state,
theme: state.theme === 'light' ? 'dark' : 'light'
};
case 'ADD_NOTIFICATION':
return {
...state,
notifications: [...state.notifications, action.payload]
};
default:
return state;
}
}
Связь между Reducer и Store
1. Store регистрирует Reducer
Cтор создаётся с reducer функцией. Reducer определяет, как изменяется состояние:
// Redux пример
import { createStore } from 'redux';
const store = createStore(reducer);
2. Reducer получает текущее состояние из Store
// Store содержит состояние
const currentState = store.getState(); // { user: null, theme: 'light', ... }
// Это состояние передаётся reducer
function reducer(state, action) { // state = currentState
// ...
}
3. Reducer возвращает новое состояние в Store
// Когда dispatch action, reducer возвращает новое состояние
store.dispatch({ type: 'SET_USER', payload: { id: '123', name: 'John' } });
// Цепочка:
// 1. dispatch отправляет action
// 2. store вызывает reducer(currentState, action)
// 3. reducer возвращает newState
// 4. store обновляет состояние
// 5. подписанные компоненты перерисовываются
Полный цикл работы
// Шаг 1: Создать store с reducer
const store = createStore(reducer);
// Шаг 2: Получить начальное состояние
let state = store.getState();
console.log(state); // { user: null, theme: 'light', notifications: [] }
// Шаг 3: Dispatch action
store.dispatch({ type: 'SET_USER', payload: { name: 'Alice' } });
// Шаг 4: Reducer обработал action и вернул новое состояние
// Reducer: (state, action) => newState
// Шаг 5: Store обновился
state = store.getState();
console.log(state); // { user: { name: 'Alice' }, theme: 'light', notifications: [] }
Практический пример в React
import { useReducer } from 'react';
interface State {
count: number;
isLoading: boolean;
}
type Action =
| { type: 'INCREMENT' }
| { type: 'DECREMENT' }
| { type: 'SET_LOADING'; payload: boolean };
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
case 'DECREMENT':
return { ...state, count: state.count - 1 };
case 'SET_LOADING':
return { ...state, isLoading: action.payload };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, {
count: 0,
isLoading: false
});
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>
Increment
</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>
Decrement
</button>
</div>
);
}
Redux в React (более сложный пример)
import { createStore } from 'redux';
import { useSelector, useDispatch } from 'react-redux';
// 1. Определить reducer
const userReducer = (state = null, action) => {
switch (action.type) {
case 'LOAD_USER':
return action.payload;
case 'LOGOUT':
return null;
default:
return state;
}
};
// 2. Создать store
const store = createStore(userReducer);
// 3. Использовать в компоненте
function UserProfile() {
const user = useSelector(state => state); // Получить состояние из store
const dispatch = useDispatch(); // Функция для отправки actions
const handleLoadUser = () => {
dispatch({ type: 'LOAD_USER', payload: { id: '1', name: 'John' } });
};
const handleLogout = () => {
dispatch({ type: 'LOGOUT' });
};
return (
<div>
{user && <p>{user.name}</p>}
<button onClick={handleLoadUser}>Load User</button>
<button onClick={handleLogout}>Logout</button>
</div>
);
}
Разница между Store и Reducer
| Aspect | Store | Reducer |
|---|---|---|
| Что это? | Объект, хранящий состояние | Функция, обновляющая состояние |
| Обязанность | Хранить и предоставлять состояние | Определить, как изменяется состояние |
| Вход | - | Текущее состояние + action |
| Выход | Состояние (через getState) | Новое состояние |
| Мутация | Никогда не мутирует напрямую | Чистая функция, не мутирует |
| Количество | Один store на приложение | Может быть много reducers |
Принципы Reducer (из Redux)
1. Чистая функция
// Плохо - мутирует state
function reducer(state, action) {
state.user = action.payload; // МУТАЦИЯ!
return state;
}
// Хорошо - возвращает новый объект
function reducer(state, action) {
return { ...state, user: action.payload };
}
2. Никаких побочных эффектов
// Плохо - побочный эффект
function reducer(state, action) {
if (action.type === 'FETCH_USER') {
fetch('/api/user').then(/* ... */); // Побочный эффект!
}
return state;
}
// Хорошо - чистая логика
function reducer(state, action) {
if (action.type === 'LOAD_USER') {
return { ...state, user: action.payload };
}
return state;
}
3. Детерминированность
// Плохо - непредсказуемо
function reducer(state, action) {
return { ...state, random: Math.random() };
}
// Хорошо - тот же input дает тот же output
function reducer(state, action) {
return { ...state, count: state.count + 1 };
}
Выводы
Store — это контейнер, который:
- Хранит состояние приложения
- Предоставляет методы для доступа к состоянию (getState)
- Принимает действия через dispatch
Reducer — это функция, которая:
- Определяет, как состояние изменяется в ответ на actions
- Всегда возвращает новое состояние
- Остаётся чистой функцией без побочных эффектов
Вместе они создают предсказуемую и тестируемую систему управления состоянием, которая делает отладку и расширение приложения гораздо проще.