瀏覽代碼

zustand persist state

AykutSarac 2 年之前
父節點
當前提交
64b7416d9f
共有 5 個文件被更改,包括 62 次插入41 次删除
  1. 1 1
      src/components/Modal/index.tsx
  2. 1 1
      src/constants/data.ts
  3. 54 38
      src/hooks/store/useConfig.tsx
  4. 5 0
      src/pages/_app.tsx
  5. 1 1
      src/typings/global.ts

+ 1 - 1
src/components/Modal/index.tsx

@@ -36,7 +36,7 @@ const Controls: React.FC<ControlProps> = ({ children, setVisible }) => {
 
   React.useEffect(() => {
     if (handleEspacePress) setVisible(false);
-  }, [handleEspacePress]);
+  }, [handleEspacePress, setVisible]);
 
   return (
     <Styled.ControlsWrapper>

+ 1 - 1
src/constants/data.ts

@@ -43,7 +43,7 @@ export const defaultConfig: StorageConfig = {
   layout: "RIGHT",
   expand: true,
   hideEditor: false,
-  zoomPanPinch: null,
+  zoomPanPinch: undefined,
   lightmode: false,
   performance: false,
 };

+ 54 - 38
src/hooks/store/useConfig.tsx

@@ -1,54 +1,70 @@
+import create from "zustand";
+import { persist } from "zustand/middleware";
 import { defaultConfig, defaultJson } from "src/constants/data";
 import { StorageConfig } from "src/typings/global";
-import create from "zustand";
 
 export interface Config {
   json: string;
   settings: StorageConfig;
   updateJson: (json: string) => void;
   loadSettings: (settings: StorageConfig) => void;
-  updateSetting: (setting: keyof StorageConfig, value: any) => void;
+  updateSetting: (setting: keyof StorageConfig, value: unknown) => void;
   zoomIn: () => void;
   zoomOut: () => void;
   centerView: () => void;
 }
 
-const useConfig = create<Config>((set) => ({
-  json: JSON.stringify(defaultJson),
-  settings: defaultConfig,
-  updateJson: (json: string) => set((state) => ({ ...state, json })),
-  loadSettings: (settings: StorageConfig) =>
-    set((state) => ({ ...state, settings })),
-  updateSetting: (setting: keyof StorageConfig, value: any) =>
-    set((state) => ({
-      ...state,
-      settings: { ...state.settings, [setting]: value },
-    })),
-  zoomIn: () =>
-    set((state) => {
-      state.settings.zoomPanPinch?.setTransform(
-        state.settings.zoomPanPinch?.state.positionX,
-        state.settings.zoomPanPinch?.state.positionY,
-        state.settings.zoomPanPinch?.state.scale + 0.4
-      );
-
-      return state;
-    }),
-  zoomOut: () =>
-    set((state) => {
-      state.settings.zoomPanPinch?.setTransform(
-        state.settings.zoomPanPinch?.state.positionX,
-        state.settings.zoomPanPinch?.state.positionY,
-        state.settings.zoomPanPinch?.state.scale - 0.4
-      );
-
-      return state;
-    }),
-  centerView: () =>
-    set((state) => {
-      state.settings.zoomPanPinch?.resetTransform();
-      return state;
+const useConfig = create(
+  persist<Config>(
+    (set, get) => ({
+      json: JSON.stringify(defaultJson),
+      settings: defaultConfig,
+      updateJson: (json: string) => set((state) => ({ ...state, json })),
+      zoomIn: () => {
+        const zoomPanPinch = get().settings.zoomPanPinch;
+        if (zoomPanPinch) {
+          zoomPanPinch.setTransform(
+            zoomPanPinch?.state.positionX,
+            zoomPanPinch?.state.positionY,
+            zoomPanPinch?.state.scale + 0.4
+          );
+        }
+      },
+      zoomOut: () => {
+        const zoomPanPinch = get().settings.zoomPanPinch;
+        if (zoomPanPinch) {
+          zoomPanPinch.setTransform(
+            zoomPanPinch?.state.positionX,
+            zoomPanPinch?.state.positionY,
+            zoomPanPinch?.state.scale - 0.4
+          );
+        }
+      },
+      centerView: () => {
+        const zoomPanPinch = get().settings.zoomPanPinch;
+        if (zoomPanPinch) zoomPanPinch.resetTransform();
+      },
+      loadSettings: (settings: StorageConfig) =>
+        set((state) => ({ ...state, settings })),
+      updateSetting: (setting: keyof StorageConfig, value: unknown) =>
+        set((state) => ({
+          ...state,
+          settings: { ...state.settings, [setting]: value },
+        })),
     }),
-}));
+    {
+      name: "config",
+      partialize: (state) =>
+        ({
+          ...state,
+          json: undefined,
+          settings: {
+            ...state.settings,
+            zoomPanPinch: undefined,
+          },
+        } as any),
+    }
+  )
+);
 
 export default useConfig;

+ 5 - 0
src/pages/_app.tsx

@@ -17,6 +17,7 @@ if (process.env.NODE_ENV !== "development") {
 }
 
 function JsonVisio({ Component, pageProps }: AppProps) {
+  const [isRendered, setRendered] = React.useState(false);
   const lightmode = useConfig((state) => state.settings.lightmode);
 
   React.useEffect(() => {
@@ -32,8 +33,12 @@ function JsonVisio({ Component, pageProps }: AppProps) {
           console.log("Service Worker registration failed: ", err);
         });
     }
+
+    setRendered(true);
   }, []);
 
+  if (!isRendered) return null;
+
   return (
     <>
       <GoogleAnalytics />

+ 1 - 1
src/typings/global.ts

@@ -6,7 +6,7 @@ export interface StorageConfig {
   layout: CanvasDirection;
   expand: boolean;
   hideEditor: boolean;
-  zoomPanPinch: ReactZoomPanPinchRef | null;
+  zoomPanPinch?: ReactZoomPanPinchRef;
   lightmode: boolean;
   performance: boolean;
 }