Как мы храним пользовательские настройки в локальном хранилище с помощью хуков в Next.js

Как мы храним пользовательские настройки в локальном хранилище с помощью хуков в Next.js

15 декабря 2023 г.

Наши пользователи хотели сохранить настройки приложения, чтобы каждый раз использовать engyne.ai, они могут запускаться с теми же настройками.

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

Engyne dashboard showing user pref settings

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

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

Настройка локального хранилища

Имя ключа будет следующим: engyne-user-prefs-{{subdomain}}. Субдомен — это имя проекта. Например - engyne-user-prefs-hackernoon.

Таким образом, каждый ключ будет иметь свой собственный UserPrefsType. Этот тип представляет настройки, которые будут сохранены.

export type UserPrefsType = {
  sortType: string,
  publishingStatusFilter: string,
  authorFilter: string,
}

Создание React Hook

Теперь, когда мы знаем ключ/значение для хранения в локальном хранилище, вот как мы создаем перехватчик React под названием useUserPrefs для сохранения и получения значения из локального хранилища.

Обратите внимание, что вы можете хранить строки только в локальном хранилище, поэтому весь JSON должен быть преобразован в строку при сохранении и анализирован при извлечении.

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

//hooks/useUserPrefs.ts

import { useEffect, useState } from "react";
import { PostPublishStatus, PostSortType } from "/types";

export type UserPrefsType = {
  sortType: string,
  publishingStatusFilter: string,
  authorFilter: string,
}

const defaultUserPrefs: UserPrefsType = {
  sortType: PostSortType.NEWEST,
  publishingStatusFilter: PostPublishStatus.ALL,
  authorFilter: "",
}

const getLocalStorage = (key: string): UserPrefsType => {
  let currentValue;
  try {
    currentValue = JSON.parse(
      localStorage.getItem(key) || JSON.stringify(defaultUserPrefs)
    );
  } catch (error) {
    return defaultUserPrefs;
  }

  return currentValue;
}

const useUserPrefs = (subdomain: string) => {
  const key = `engyne-user-prefs-${subdomain}`

  const [value, setValue] = useState<UserPrefsType>(() => {
    if (!subdomain) return defaultUserPrefs;
    return getLocalStorage(key)
  });

  useEffect(() => {
    if (!subdomain) return;
    const currentValue = getLocalStorage(key);
    setValue(currentValue);
  }, [subdomain])

  useEffect(() => {
    if (!subdomain || !value) return;
    localStorage.setItem(key, JSON.stringify(value))
  }, [value])

  const updateUserPrefs = (userPref: Partial<UserPrefsType>) => {
    if (!subdomain) return;
    const currentValue = getLocalStorage(key);
    const updatedUserPrefs = { ...currentValue, ...userPref }
    setValue(updatedUserPrefs);
  }

  return { userPrefs: value, updateUserPrefs };
};

export default useUserPrefs;

Используйте хук в приложении

Теперь мы можем импортировать этот хук в приложение и получить сохраненное значение автора из локального хранилища. Сначала мы настраиваем перехватчик для получения пользовательских настроек указанного проекта, затем устанавливаем значение автора с помощью userPrefs.authorFilter.

updateUserPrefs используется всякий раз, когда пользователь выбирает другое имя автора.

import {
  Select,
} from "@chakra-ui/react";

const subdomain = "hackernoon"

const { userPrefs, updateUserPrefs } = useUserPrefs(subdomain)
const authorsData = ["Author 1", "Author 2"]

// in component

<Select size="md" color="gray.600" width="unset" variant="unstyled" placeholder="Select author" onChange={(evt) => {
                  updateUserPrefs({ authorFilter: evt.target.value })
                }} value={userPrefs.authorFilter}>
                  {authorsData.map((author: any, i: number) => (
                    <option key={`author_${i}`} value={author.id}>
                      {author.name}
                    </option>
                  ))}
                </Select>

Вот как выглядят сохраненные пользовательские настройки в локальном хранилище. Значения локального хранилища для Engine


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE