Отслеживание изменений состояния с помощью плагина Zustand

Отслеживание изменений состояния с помощью плагина Zustand

Отслеживание изменений состояния с помощью плагина Zustand

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

Установка плагина

Section titled Установка плагина

Плагин легко установить с помощью следующей команды:

npm i @openreplay/tracker-zustand

Использование плагина в приложении Next.js

Section titled Использование плагина в приложении Next.js

В этом примере мы будем использовать то же самое приложение, что показано в руководстве по Next.js для нашего трекера, поэтому, если вам нужны дополнительные сведения об используемом провайдере Context, сначала ознакомьтесь с ним.

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

Провайдер Context, который я использую, позволяет настраивать плагины трекера, поэтому после установки плагина мы изменим файл _app.tsx, добавив приведённую ниже инструкцию import:

import trackerZustand from '@openreplay/tracker-zustand'

А затем основная функция App должна выглядеть так:

export default function MyApp({ Component, pageProps }: AppProps) {
  const Layout = (Component as any).Layout || Noop

  useEffect(() => {
    document.body.classList?.remove('loading')
  }, [])

  let plugins = [
    {
      fn: trackerZustand,
      name: 'zustand',
    },
  ]

  return (
    <TrackerProvider
      config={{
        plugins
      }}
    >
      <Head />
      <ManagedUIContext>
        <Layout pageProps={pageProps}>
          <Component {...pageProps} />
        </Layout>
      </ManagedUIContext>
    </TrackerProvider>
  )
}

Это автоматически инициализирует плагин вместе с трекером, а также сделает доступными данные, возвращаемые при выполнении основной функции плагина.

Следующий шаг — создать хранилище (store); через минуту мы будем добавлять в это хранилище товары с сайта электронной коммерции.

Создание хранилища с помощью плагина Zustand

Section titled Создание хранилища с помощью плагина Zustand

Использование плагина требует изменить способ, которым вы обычно создаёте экземпляр хранилища Zustand, поэтому можете смело скопировать и вставить следующий код в качестве шаблона:

import create from 'zustand'

const productStore = null
export const useProductsStore = (logger) => {
  if (!productStore) {
    //use a singleton pattern to make sure we only create the store the first time around
    productStore = createProductStore(logger)
  }
  return productStore
}

function createProductStore(logger) {
  return create(
    logger((set) => ({
      products: [],
      addProduct: (p) =>
        set((state) => {
          const prodFound = state.products.find((prod) => {
            return p.id == prod.id
          })
          if (prodFound) {
            p.amount = prodFound.amount + 1
          } else {
            p.amount = 1
          }

          return {
            products: [...state.products.filter((prod) => p.id != prod.id), p],
          }
        }),
    }))
  )
}

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

С другой стороны, функция createProductStore создаст хранилище, задаст логику для метода addProduct и использует функцию logger, которую мы ей предоставляем. Этот logger, как вы, вероятно, уже догадались, — это тот самый, который мы получили при использовании плагина Zustand.

Когда хранилище готово, мы можем начать добавлять в него товары.

Добавление товаров в наше хранилище

Section titled Добавление товаров в наше хранилище

Хранилище экспортирует метод addProduct, который отвечает за отслеживание товаров в нашей корзине.

Чтобы импортировать функцию в свой код, вам нужно:

  1. Импортировать и использовать провайдер Context трекера.
  2. Получить атрибут pluginsReturnedValue из контекста.
  3. Использовать его для вызова метода zustand (обратите внимание, что метод назван по атрибуту name, который мы указали при настройке плагина выше), и передать строковый атрибут, чтобы дать хранилищу имя (это имя будет использоваться во время воспроизведения).
  4. Метод zustand вернёт logger, который мы будем использовать при вызове хука useProductStore из zustand (того, что мы создали для хранилища).

Всё это кажется слишком сложным, но по сути всё сводится к следующему:

const { pluginsReturnedValues } = useContext(TrackerContext)

const useProductStoreTracked = useProductsStore(
  pluginsReturnedValues.zustand('products_store')
)
const { addProduct } = useProductStoreTracked()

Теперь вы можете просто вызвать метод addProduct, и он добавит товары из корзины в хранилище.

Чтение данных из хранилища

Section titled Чтение данных из хранилища

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

Вот так:

const { pluginsReturnedValues } = useContext(TrackerContext)

const useProductStoreTracked = useProductsStore(
  pluginsReturnedValues.zustand('products_store')
)
const { products } = useProductStoreTracked()

Затем вы можете перебирать products как обычно:

<div>
  {products.map((p: Product, idx: Number) => {
    return (
      <div key={+idx}>
        {p.name}({p.amount})
      </div>
    )
  })}
</div>

Приведённый выше код перебирает список товаров и отображает их на экране. Каждый раз, когда вы добавляете в хранилище новый товар, он также будет обновляться здесь.

Синхронизация состояния с воспроизведением сессии

Section titled Синхронизация состояния с воспроизведением сессии

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

Новая вкладка для данных, отслеживаемых Zustand

При нажатии на неё вы увидите содержимое хранилища и сможете понять, как оно меняется, а также какие данные в нём сохранены:

Данные состояния, отображаемые во время воспроизведения

Обратите внимание на имя хранилища: это именно то имя, которое мы использовали при первом вызове метода zustand.

Если вы используете не Next.js, а другой фреймворк, способ его использования должен быть аналогичным; ключевым моментом является то, как вы создаёте хранилище. Пока вы находите способ использовать функцию logger при его создании, вы сможете отслеживать состояние во время воспроизведения.

Вы можете ознакомиться с этим репозиторием, чтобы увидеть полный исходный код работающего приложения Next.js с плагином Zustand.

Если у вас возникнут какие-либо проблемы с настройкой плагина Zustand в вашем проекте, свяжитесь с нами в нашем сообществе Slack и задайте вопрос напрямую нашим разработчикам!