← Назад к вопросам

Что такое useReducer?

2.3 Middle🔥 161 комментариев
#Другое

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое useReducer?

useReducer — это React хук (Hook) для управления состоянием компонента. Это более сложная альтернатива useState, которая используется когда состояние имеет сложную структуру и требует множества различных действий для его изменения. useReducer позволяет обновлять состояние на основе действий (actions) через функцию-редюсер (reducer).

Отметим, что useReducer — это JavaScript/React концепция, не Python. Однако я объясню принцип, так как он применим и в других контекстах.

Основная концепция

const [state, dispatch] = useReducer(reducer, initialState);

Где:

  • state — текущее состояние
  • dispatch — функция для отправки действий
  • reducer — функция, которая определяет, как обновлять состояние
  • initialState — начальное состояние

Пример простого счётчика

import { useReducer } from 'react';

// 1. Функция редюсер
function counterReducer(state, action) {
    switch(action.type) {
        case 'INCREMENT':
            return { count: state.count + 1 };
        case 'DECREMENT':
            return { count: state.count - 1 };
        case 'RESET':
            return { count: 0 };
        default:
            return state;
    }
}

// 2. Компонент
function Counter() {
    const initialState = { count: 0 };
    const [state, dispatch] = useReducer(counterReducer, initialState);
    
    return (
        <div>
            <p>Count: {state.count}</p>
            <button onClick={() => dispatch({ type: 'INCREMENT' })}>
                +
            </button>
            <button onClick={() => dispatch({ type: 'DECREMENT' })}>
                -
            </button>
            <button onClick={() => dispatch({ type: 'RESET' })}>
                Reset
            </button>
        </div>
    );
}

Более сложный пример: управление формой

function formReducer(state, action) {
    switch(action.type) {
        case 'FIELD_CHANGE':
            return {
                ...state,
                [action.field]: action.value
            };
        case 'RESET':
            return { name: '', email: '', message: '' };
        case 'SUBMIT':
            return {
                ...state,
                submitted: true
            };
        default:
            return state;
    }
}

function ContactForm() {
    const [state, dispatch] = useReducer(formReducer, {
        name: '',
        email: '',
        message: ''
    });
    
    const handleChange = (e) => {
        dispatch({
            type: 'FIELD_CHANGE',
            field: e.target.name,
            value: e.target.value
        });
    };
    
    const handleSubmit = (e) => {
        e.preventDefault();
        dispatch({ type: 'SUBMIT' });
        console.log('Form submitted:', state);
    };
    
    return (
        <form onSubmit={handleSubmit}>
            <input 
                name="name" 
                value={state.name} 
                onChange={handleChange} 
            />
            <input 
                name="email" 
                value={state.email} 
                onChange={handleChange} 
            />
            <textarea 
                name="message" 
                value={state.message} 
                onChange={handleChange} 
            />
            <button type="submit">Submit</button>
            <button type="button" onClick={() => dispatch({ type: 'RESET' })}>
                Reset
            </button>
        </form>
    );
}

useReducer vs useState

// useState — для простого состояния
const [count, setCount] = useState(0);

// useReducer — для сложного состояния с множеством действий
const [state, dispatch] = useReducer(reducer, initialState);
ХарактеристикаuseStateuseReducer
СложностьПростаяСредняя
СостояниеПримитивный типОбъект/массив
Действия1-2Много разных
Логика обновленияВ компонентеВ функции редюсер
ТестированиеСложнееПроще (чистая функция)

Пример с асинхронными действиями

const initialState = {
    loading: false,
    data: null,
    error: null
};

function dataReducer(state, action) {
    switch(action.type) {
        case 'LOADING':
            return { ...state, loading: true };
        case 'SUCCESS':
            return { loading: false, data: action.payload, error: null };
        case 'ERROR':
            return { loading: false, data: null, error: action.payload };
        default:
            return state;
    }
}

function DataFetcher() {
    const [state, dispatch] = useReducer(dataReducer, initialState);
    
    const fetchData = async () => {
        dispatch({ type: 'LOADING' });
        try {
            const response = await fetch('/api/data');
            const data = await response.json();
            dispatch({ type: 'SUCCESS', payload: data });
        } catch(error) {
            dispatch({ type: 'ERROR', payload: error.message });
        }
    };
    
    return (
        <div>
            {state.loading && <p>Loading...</p>}
            {state.error && <p>Error: {state.error}</p>}
            {state.data && <p>Data: {JSON.stringify(state.data)}</p>}
            <button onClick={fetchData}>Fetch</button>
        </div>
    );
}

Преимущества useReducer

  • Организация кода — логика обновления отделена от компонента
  • Тестируемость — редюсер — это чистая функция, легко тестировать
  • Масштабируемость — удобен для сложного состояния
  • Предсказуемость — все изменения проходят через редюсер
  • Отладка — легче отследить, какое действие привело к изменению состояния

Аналогия с Python

В Python похожую логику можно реализовать через классы с методами:

class Counter:
    def __init__(self):
        self.state = {'count': 0}
    
    def dispatch(self, action):
        if action['type'] == 'INCREMENT':
            self.state['count'] += 1
        elif action['type'] == 'DECREMENT':
            self.state['count'] -= 1
        elif action['type'] == 'RESET':
            self.state['count'] = 0
        return self.state

useReducer — это мощный инструмент для управления сложным состоянием в React приложениях, особенно когда требуется многошаговая логика обновления или координация нескольких частей состояния.

Что такое useReducer? | PrepBro