Рекомендации по управлению состоянием
Эффективное управление состоянием — ключ к поддерживаемому и читаемому коду в React Native. Ниже приведены основные рекомендации, которые помогут избежать распространённых ошибок и упростят развитие приложения.
Не храните вычисляемые данные в состоянии
Если значение можно получить из других частей состояния или пропсов, не сохраняйте его отдельно. Это снижает риск рассинхронизации и уменьшает объём данных.
Неправильно:
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [fullName, setFullName] = useState(''); // избыточно
// При каждом изменении имени нужно обновлять fullName
Правильно:
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const fullName = `${firstName} ${lastName}`; // вычисляется при рендере
Разделяйте локальное и глобальное состояние
- Локальное состояние (
useState,useReducer) — для данных, нужных только внутри одного компонента или экрана (например, текст в поле ввода, открытый аккордеон). - Глобальное состояние (
useContextили внешние библиотеки) — для данных, используемых во многих частях приложения (тема, авторизация, настройки).
Не стоит «поднимать» состояние выше, чем это действительно необходимо. Излишнее использование контекста усложняет отладку и вызывает лишние перерисовки.
Передавайте функции через контекст осторожно
Контекст лучше использовать для передачи данных, а не поведения. Однако если вы всё же передаёте функции управления состоянием (например, toggleTheme), обязательно мемоизируйте их с помощью useCallback. Иначе каждый рендер провайдера будет создавать новую функцию, что приведёт к ненужным обновлениям всех потребителей контекста.
Пример правильного подхода:
const [darkMode, setDarkMode] = useState(false);
const toggleTheme = useCallback(() => {
setDarkMode(prev => !prev);
}, []);
<ThemeContext.Provider value={{ darkMode, toggleTheme }}>
Минимизируйте количество состояний
Объединяйте связанные значения в один объект состояния, если они обновляются вместе:
// Лучше так
const [formState, setFormState] = useState({ email: '', password: '' });
// Чем так
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
Это особенно актуально при использовании useReducer, где структура состояния уже централизована.
Планируйте расширяемость
Даже если сейчас состояние простое, подумайте, как оно может измениться в будущем. Например, вместо булева флага isLoading иногда полезнее использовать строковый статус ('idle' | 'loading' | 'success' | 'error'), если возможны разные типы загрузки.
Следуя этим принципам, вы создадите приложение, в котором легко вносить изменения, находить ошибки и добавлять новые функции.