reactjs 切换用户配置文件时,如何正确管理Next.js项目中的本地存储数据?

rmbxnbpk  于 2023-10-17  发布在  React
关注(0)|答案(1)|浏览(99)

我正在开发一个React/Nextjs应用程序,在这个应用程序中,我使用了一个自定义的useLocalStorage钩子来管理用户配置文件的本地存储。我在模仿一个聊天gpt应用。
然而,我遇到了一个问题,新配置文件的本地存储数据似乎保留了以前配置文件的值,导致了不正确的行为。
下面是我的应用程序的结构的简要描述:
我有不同的用户配置文件。每个配置文件都有自己的密钥,例如:profile 1-chats,profile 2-chats等等。我使用useLocalStorage钩子,并根据当前用户的配置文件动态生成一个键。
当用户切换配置文件时,新的配置文件将在应用程序状态中正确设置。
我正在使用Provider访问我的应用中的此值。

export const ChatProvider: React.FC<ChatProviderProps> = ({ children }) => {
  const [userProfile, setUserProfile] = useState<ProfileType>(
    UserProfiles.Profile1
  );

  const [chats, setChats] = useLocalStorage(
    `${userProfile.title}-chats`,
    initialState
  );

// ....

这是我用来处理localStorage的自定义钩子,在做了一些调查之后,我发现这是在Nextjs中处理它的方法。

// CUSTOM HOOK TO HANDLE LOCAL STORAGE IN NEXTJS
import { useEffect, useState } from "react";

const useLocalStorage = <T>(
  key: string,
  initialState: T
): [T, React.Dispatch<React.SetStateAction<T>>] => {
  const [state, setState] = useState<T>(() => {
    if (typeof window !== "undefined") {
      try {
        const item = localStorage.getItem(key);
        return item ? JSON.parse(item) : initialState;
      } catch (error) {
        console.error("Error parsing local storage data:", error);
      }
    }
    return initialState;
  });

  useEffect(() => {
    if (typeof window !== "undefined") {
      try {
        localStorage.setItem(key, JSON.stringify(state)); // I think the problem is here, when i change profile, the state has the values of last profile and it is setting that values to the new profile key
      } catch (error) {
        console.error("Error saving data to local storage:", error);
      }
    }
  }, [key, state]);

  return [state, setState];
};

export default useLocalStorage;

这是我更改用户配置文件的组件

const SelectProfileModal = ({
  isOpen,
  onClose,
  onConfirm,
}: SelectProfileModalProps) => {
  const { userProfile, setUserProfile } = useChatContext();
  const router = useRouter();
  const [selectedProfile, setSelectedProfile] =
    useState<ProfileType>(userProfile);

  const handleOnSave = () => {
    setUserProfile(selectedProfile);
    router.push("/");
    onClose();
  };

  return (
    <Modal show={isOpen} onHide={onClose}>
      <ModalHeader closeButton>
        <Modal.Title>Select Profile</Modal.Title>
      </ModalHeader>
      <ModalBody>
        <ListGroup>
          {AvailableProfiles.map((profile) => (
            <ListGroup.Item
              key={profile.id}
              action
              variant="dark"
              onClick={() => setSelectedProfile(profile)}
              active={selectedProfile.id === profile.id}
            >
              {profile.id}- {profile.title}
            </ListGroup.Item>
          ))}
        </ListGroup>
      </ModalBody>
      <ModalFooter>
        <Button variant="secondary" onClick={onClose}>
          Cancel
        </Button>
        <Button variant="primary" onClick={handleOnSave}>
          Select
        </Button>
      </ModalFooter>
    </Modal>
  );
};

我面临的问题是,即使我在应用程序状态下成功切换配置文件,当我切换到不同的配置文件时,本地存储似乎保留了前一个配置文件中的数据,导致意外行为。

我怀疑这个问题可能与用户切换时为新配置文件初始化本地存储的方式有关。但是,我已经检查了我的代码和useLocalStorage钩子,它们似乎是正确的。
我是NextJS的新手。
我正在寻求有关如何解决此问题的建议。具体而言:
如何确保本地存储正确地为新配置文件初始化?
我将感谢任何指导或建议,以帮助我解决这个问题。如果您需要查看我的代码的特定部分或其他细节,请告诉我。
堆栈:

"next": "^13.4.12",
    "react": "^18.2.0",

谢谢您的帮助!
预期结果:我用Profile 1问了一个问题,它被正确地存储在localStorage的profile 1-chats键中,然后我切换到Profile 2,localStorage中的一个新键应该用空的[]初始化。如果我使用Profile 2提问,它应该存储在相应的localstorage key中。
当前结果:我使用Profile 1问了一个问题,它被正确地存储在localStorage的profile 1-chats键中,然后我切换到Profile 2,localStorage中的一个新键被初始化(profile 2-chats),但profile 1-chats的值被复制到profile 2-chats。

xqnpmsa8

xqnpmsa81#

我认为,在您提供的代码中,状态初始化仅在组件挂载时执行一次,并且它取决于作为参数提供的键。如果键在组件已经挂载之后发生了更改,则状态不会自动更新以响应键的更改。
你可以添加这几行代码:

// Use useEffect to watch for changes in the key
  useEffect(() => {
    if (key) {
      const storedItem = localStorage.getItem(key);
      if (storedItem) {
        try {
          const parsedItem = JSON.parse(storedItem);
          setState(parsedItem);
        } catch (error) {
          console.error("Error parsing local storage data:", error);
        }
      }
    }
  }, [key]);

这是一个粗糙的工作,所以请让我知道,如果这是喊任何错误。

相关问题