Як працює управління станом в React?
Управління станом - це один з найважливіших аспектів розробки React додатків. Розглянемо різні підходи та їх використання.
Типи стану
1. Локальний стан компонента
Найпростіший тип стану, який належить конкретному компоненту:
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<span>{count}</span>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
2. Підняття стану вгору (Lifting State Up)
Коли кілька компонентів потребують доступу до одного стану:
function App() {
const [user, setUser] = useState(null);
return (
<div>
<Header user={user} />
<Profile user={user} setUser={setUser} />
</div>
);
}
Розширені рішення
Context API
Для передачі даних через дерево компонентів без prop drilling:
const UserContext = createContext();
function UserProvider({ children }) {
const [user, setUser] = useState(null);
return (
<UserContext.Provider value={{ user, setUser }}>
{children}
</UserContext.Provider>
);
}
function Profile() {
const { user, setUser } = useContext(UserContext);
// ...
}
Кастомні хуки для стану
function useUser() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(false);
const login = async (credentials) => {
setLoading(true);
try {
const userData = await loginAPI(credentials);
setUser(userData);
} finally {
setLoading(false);
}
};
return { user, loading, login };
}
Зовнішні бібліотеки
Redux
Для складних додатків з передбачуваним управлінням станом:
// Reducer
function counterReducer(state = { count: 0 }, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
default:
return state;
}
}
// Component
function Counter() {
const count = useSelector(state => state.count);
const dispatch = useDispatch();
return (
<button onClick={() => dispatch({ type: 'INCREMENT' })}>
{count}
</button>
);
}
Zustand
Легка альтернатива Redux:
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));
function Counter() {
const { count, increment } = useStore();
return <button onClick={increment}>{count}</button>;
}
Коли використовувати кожен підхід
Локальний стан (useState)
- Стан належить тільки одному компоненту
- Прості форми, тогли, локальні UI стани
Context API
- Дані потрібні багатьом компонентам
- Теми, мовні налаштування, інформація про користувача
Redux/Zustand
- Складна логіка оновлення стану
- Потреба в middleware (логування, async actions)
- Великі додатки з багатьма взаємопов'язаними станами
Найкращі практики
- Починайте з локального стану - не ускладнюйте без потреби
- Підіймайте стан тільки коли потрібно - тримайте стан якомога нижче
- Використовуйте Context обережно - може призвести до зайвих ре-рендерів
- Розділяйте логіку та UI - виносьте бізнес-логіку в кастомні хуки
Правильний вибір підходу до управління станом значно спрощує розробку та підтримку додатка.