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

Бывают ли state manager только глобальными

2.0 Middle🔥 91 комментариев
#State Management

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

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

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

Бывают ли state manager только глобальными?

Ответ: НЕТ. State manager может быть локальным, глобальным или гибридным. Давайте разберёмся в разных подходах.

Типы state manager

1. Локальный (Local) state Состояние живёт в одном компоненте:

function Counter() {
  const [count, setCount] = useState(0); // локальный state
  
  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  );
}

2. Компонентный (Component tree) state Состояние передаётся через props в дереве компонентов:

function Parent() {
  const [user, setUser] = useState(null);
  
  return (
    <div>
      <Child user={user} onUserChange={setUser} />
      <Sibling user={user} />
    </div>
  );
}

3. Контекстный (Context) state Состояние доступно всем компонентам в Provider'е:

const UserContext = createContext();

function App() {
  const [user, setUser] = useState(null);
  
  return (
    <UserContext.Provider value={{ user, setUser }}>
      <Header />
      <Main />
      <Footer />
    </UserContext.Provider>
  );
}

function Header() {
  const { user } = useContext(UserContext); // доступно везде
}

4. Глобальный (Global) state Единое хранилище для всего приложения:

// Redux, Zustand, MobX
const store = createStore({ user: null, settings: {} });

app.use(store); // доступно везде в приложении

Сравнение подходов

ТипОбластьПроизводительностьСложностьИспользование
Local stateКомпонентОтличноМинимальнаяuseState для UI
Component treeПоддеревоХорошоМалаяProps drilling
ContextProviderOKСредняяГлобальные настройки
GlobalВсё приложениеOKБольшаяСложное состояние

Локальные state manager

Использование local state правильно:

// Хорошо - локальное состояние для UI
function Accordion() {
  const [isOpen, setIsOpen] = useState(false); // только для этого компонента
  
  return (
    <div>
      <button onClick={() => setIsOpen(!isOpen)}>Toggle</button>
      {isOpen && <Content />}
    </div>
  );
}

// Хорошо - форма обновляется локально
function LoginForm() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  
  const handleSubmit = async () => {
    await api.login(email, password);
  };
  
  return (
    <form onSubmit={handleSubmit}>
      <input value={email} onChange={(e) => setEmail(e.target.value)} />
      <input value={password} onChange={(e) => setPassword(e.target.value)} />
      <button type="submit">Login</button>
    </form>
  );
}

Миксированный подход

Лучший способ - использовать оба:

// Global state - для данных приложения
const useAuth = () => useContext(AuthContext); // user, permissions

// Local state - для UI
function Modal() {
  const [isOpen, setIsOpen] = useState(false); // только для модала
  const { user } = useAuth(); // глобальные данные
  
  return (
    <dialog open={isOpen}>
      <p>Hello, {user?.name}</p>
      <button onClick={() => setIsOpen(false)}>Close</button>
    </dialog>
  );
}

Примеры правильного использования

Локальный state:

// Toggle, accordion, modal, form input, loading state
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [selectedTab, setSelectedTab] = useState('tab1');
const [formData, setFormData] = useState({ name: '', email: '' });

Глобальный state:

// Authenticated user, app theme, language, permissions
const { user, theme, language, permissions } = useAppState();

Типы state managers

1. React Context (встроенный)

const ThemeContext = createContext();

function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

2. Zustand (простой и легкий)

const useStore = create((set) => ({
  user: null,
  setUser: (user) => set({ user }),
}));

function App() {
  const { user, setUser } = useStore();
}

3. Redux (полнофункциональный)

const store = configureStore({
  reducer: {
    user: userReducer,
    settings: settingsReducer,
  },
});

function App() {
  const user = useSelector(state => state.user);
  const dispatch = useDispatch();
}

4. MobX (reactive)

class UserStore {
  user = null;
  
  setUser(user) {
    this.user = user;
  }
}

const userStore = new UserStore();

Как выбрать?

Используй local state если:

  • Состояние нужно только одному компоненту
  • Состояние меняется часто (но влияет на один компонент)
  • Это UI состояние (isOpen, selectedTab, formData)
// Идеально для local state
function SearchBox() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);
  const [loading, setLoading] = useState(false);
  
  return (
    <div>
      <input value={query} onChange={(e) => setQuery(e.target.value)} />
      {loading && <Spinner />}
      {results.map(item => <Item key={item.id} {...item} />)}
    </div>
  );
}

Используй Context если:

  • Состояние нужно нескольким компонентам
  • Состояние редко меняется (theme, language)
  • Нет глубокого nesting (prop drilling)
// Идеально для Context
const LanguageContext = createContext();

function LanguageProvider({ children }) {
  const [language, setLanguage] = useState('en');
  return (
    <LanguageContext.Provider value={{ language, setLanguage }}>
      {children}
    </LanguageContext.Provider>
  );
}

Используй global state если:

  • Состояние нужно везде в приложении
  • Состояние часто меняется (очень активно используется)
  • Нужна сложная логика обновления (reducers)
// Идеально для global state (Zustand, Redux)
const useAppStore = create((set) => ({
  user: null,
  notifications: [],
  setUser: (user) => set({ user }),
  addNotification: (notif) => set((state) => ({
    notifications: [...state.notifications, notif]
  })),
}));

Анти-паттерны

Не делай так:

// Плохо - всё в global state
const useStore = create(set => ({
  isMenuOpen: false,        // это локальное UI
  selectedFormTab: 'tab1',  // это локальное UI
  user: null,               // это глобальное
  permissions: [],          // это глобальное
}));

// Хорошо - разделение
function Menu() {
  const [isOpen, setIsOpen] = useState(false); // локальное
}

const useAppStore = create(set => ({
  user: null,
  permissions: [],
}));

Оптимизация производительности

Local state - лучше для производительности:

// Плохо - весь компонент перерендерится
const [count, setCount] = useState(0); // в global state

// Хорошо - только этот компонент
function Counter() {
  const [count, setCount] = useState(0); // local state
}

Context - может быть медленным:

// Плохо - весь Provider перерендерится
const ThemeContext = createContext();

function ThemeProvider() {
  const [theme, setTheme] = useState('light');
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {/* Всё перерендерится при изменении theme */}
    </ThemeContext.Provider>
  );
}

// Хорошо - разделить Context
const ThemeValueContext = createContext();
const ThemeActionsContext = createContext();

Итог

State manager НЕ только глобальный:

  1. Local state - для одного компонента (useState)
  2. Props - для соседних компонентов (props drilling)
  3. Context - для поддерева компонентов (глобальные настройки)
  4. Global state - для всего приложения (Redux, Zustand)

Правило: используй самый простой уровень, который подходит для твоего сценария. Начинай с local state, поднимайся выше только если нужно.

local state (useState)
    ↓
props (prop drilling)
    ↓
Context API (глобальные настройки)
    ↓
Global store (сложное состояние)
Бывают ли state manager только глобальными | PrepBro