Как использовать Zustand для управления состоянием

На список статей
Blog image

Track My Time — Управляй временем эффективно и достигай большего!
"Ваш незаменимый помощник в управлении проектами и учете времени! Отслеживайте задачи, распределяйте ресурсы и контролируйте каждую минуту работы. Повышайте эффективность, упрощайте процессы и достигайте результатов быстрее. Начните работать с нами и добейтесь успеха вместе!"

Zustand – это легковесная библиотека для управления состоянием в React-приложениях. Она проста в использовании и обладает высокой производительностью. Если вы знакомы с Redux, возможно, вас радует его мощность, но иногда вам может казаться, что нужно слишком много кода для решения простых задач. Вот здесь и приходит на помощь Zustand.

Эта библиотека предлагает современный и минималистичный подход, позволяющий управлять состоянием приложения без лишней сложности. Zustand использует простой синтаксис, который легко освоить, особенно для начинающих. Главное его преимущество – это способность сохранять минимальный объем кода при управлении сложными состояниями.


Преимущества использования Zustand

Zustand популярен среди разработчиков, благодаря следующим преимуществам:

  1. Простота использования: Установка и интеграция библиотеки не требует много усилий. Даже если вы не работали раньше с библиотеками для управления состоянием, вам будет просто начать.
  2. Маленький размер: Zustand легковесен и минимально нагружает проект, что положительно сказывается на производительности приложения.
  3. Отсутствие шаблонного кода: Вам не нужно писать много дополнительных редьюсеров, действий или шаблонных структур, как это требуется в Redux.
  4. Легкость в тестировании: Zustand легко тестировать благодаря его простой архитектуре.
  5. Поддержка автоматического разделения состояний: Вы можете создавать несколько "store" для разных частей приложения, что помогает лучше организовать код.

Установка и настройка Zustand

Чтобы начать использовать Zustand, сначала установим его в ваш проект. Это делается через пакетный менеджер, например, npm или Yarn:

npm install zustand

Или:

yarn add zustand

После установки можно приступить к созданию состояния. В Zustand создается хранилище (store), которое хранит состояние и функции для его обновления.


Управление простым состояниями

Создадим простой store для управления счётчиком:

import create from 'zustand';

// Создаем хранилище состояния
const useStore = create(set => ({
 count: 0,
 increase: () => set(state => ({ count: state.count + 1 })),
 decrease: () => set(state => ({ count: state.count - 1 })),
}));

В этом примере мы создаём состояние count, которое изначально равно 0, и две функции: increase для увеличения значения и decrease для уменьшения.

Теперь, чтобы использовать это состояние в компоненте, просто вызываем useStore:

import React from 'react';
import { useStore } from './store';

const Counter = () => {
 const { count, increase, decrease } = useStore();
 
 return (
   <div>
     <h1>{count}</h1>
     <button onClick={increase}>Увеличить</button>
     <button onClick={decrease}>Уменьшить</button>
   </div>
 );
};

export default Counter;


Управление сложными состояниями

Zustand позволяет легко управлять как простыми, так и более сложными состояниями. Например, если у вас в приложении есть несколько сущностей, вы можете разделить их состояния:

const useUserStore = create(set => ({
 users: [],
 addUser: (user) => set(state => ({ users: [...state.users, user] })),
}));

const useTodoStore = create(set => ({
 todos: [],
 addTodo: (todo) => set(state => ({ todos: [...state.todos, todo] })),
}));


Допустим, у вас есть приложение с пользователями и задачами. Чтобы взаимодействовать с ними, можно создавать отдельные компоненты для каждого:

import React, { useState } from 'react';
import { useUserStore } from './userStore';
import { useTodoStore } from './todoStore';

const App = () => {
 const { users, addUser } = useUserStore();
 const { todos, addTodo } = useTodoStore();
 const [newUser, setNewUser] = useState('');
 const [newTodo, setNewTodo] = useState('');

 return (
   <div>
     <h2>Пользователи</h2>
     <ul>
       {users.map((user, index) => (
         <li key={index}>{user}</li>
       ))}
     </ul>
     <input
       type="text"
       value={newUser}
       onChange={(e) => setNewUser(e.target.value)}
       placeholder="Добавить пользователя"
     />
     <button onClick={() => addUser(newUser)}>Добавить</button>

     <h2>Задачи</h2>
     <ul>
       {todos.map((todo, index) => (
         <li key={index}>{todo}</li>
       ))}
     </ul>
     <input
       type="text"
       value={newTodo}
       onChange={(e) => setNewTodo(e.target.value)}
       placeholder="Добавить задачу"
     />
     <button onClick={() => addTodo(newTodo)}>Добавить</button>
   </div>
 );
};

export default App;

Теперь у вас есть список пользователей и задач, которые управляются через отдельные хранилища, и взаимодействовать с ними очень просто!

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

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

const useUserStore = create((set) => ({
 users: [],
 fetchUsers: async () => {
   const response = await fetch('https://api.example.com/users');
   const data = await response.json();
   set({ users: data });
 },
}));

Затем вы можете использовать эту функцию в компоненте:

import React, { useEffect } from 'react';
import { useUserStore } from './userStore';

const Users = () => {
 const { users, fetchUsers } = useUserStore();

 useEffect(() => {
   fetchUsers();
 }, [fetchUsers]);

 return (
   <div>
     <h2>Список пользователей</h2>
     <ul>
       {users.map((user, index) => (
         <li key={index}>{user.name}</li>
       ))}
     </ul>
   </div>
 );
};

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

Zustand хорошо оптимизирован для производительности и не вызывает повторных рендеров компонентов, если это не необходимо. Когда вы вызываете функцию обновления состояния, она будет вызывать повторный рендер только для тех компонентов, которые зависят от изменяемого состояния. Это особенно полезно в больших приложениях, где важна оптимизация рендеров.

Чтобы сделать работу еще более эффективной, можно использовать селекторы. Это позволяет компоненту подписываться только на определенные части состояния и реагировать только на их изменения:

const useCount = () => useStore((state) => state.count);

const Counter = () => {
 const count = useCount();
 return <h1>{count}</h1>;
};

В этом случае компонент будет перерендериваться только тогда, когда изменится count, а не всё состояние.


Комментарии

Пока нет комментариев

Добавить комментарий