Skip to content

Commit

Permalink
feat: hooks usePersistentState and usePrevious
Browse files Browse the repository at this point in the history
  • Loading branch information
receter committed Oct 22, 2024
1 parent 5d3d4d5 commit 5174fd4
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 16 deletions.
29 changes: 29 additions & 0 deletions packages/utils/lib/hooks/usePersistentState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useState, useEffect } from "react";

export function usePersistentState<Type>(
key: string,
initialState: Type | (() => Type),
options: { storagePrefix?: string; storage?: Storage } = {}
): [Type, React.Dispatch<React.SetStateAction<Type>>] {
const { storagePrefix = "use-persistent-state-", storage = localStorage } =
options;
const prefixedKey = storagePrefix + key;
// read key from the specified storage if not found use default value
const [value, setValue] = useState<Type>(() => {
const storedValue = storage.getItem(prefixedKey);
if (storedValue === null) {
if (typeof initialState === "function") {
return (initialState as () => Type)();
} else {
return initialState;
}
} else {
return JSON.parse(storedValue);
}
});
// update the specified storage when value changes
useEffect(() => {
storage.setItem(prefixedKey, JSON.stringify(value));
}, [value, prefixedKey, storage]);
return [value, setValue];
}
9 changes: 9 additions & 0 deletions packages/utils/lib/hooks/usePrevious.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useEffect, useRef } from "react";

export function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T>();
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
3 changes: 3 additions & 0 deletions packages/utils/lib/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,6 @@ export function accessibleOnClick(
onClick: handler,
};
}

export { usePersistentState } from "./hooks/usePersistentState";
export { usePrevious } from "./hooks/usePrevious";
9 changes: 6 additions & 3 deletions packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@
},
"devDependencies": {
"@types/node": "^18.16.1",
"typescript": "^5.0.2",
"@types/react-dom": "^18.3.1",
"@types/react": "^18.3.11",
"typescript": "^5.6.3",
"vite": "^4.3.2",
"vite-plugin-dts": "^3.9.1"
},
"dependencies": {
"@types/react": "^18.3.3"
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
3 changes: 3 additions & 0 deletions packages/utils/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ export default defineConfig({
entry: resolve(__dirname, "lib/main.ts"),
formats: ["es"],
},
rollupOptions: {
external: ["react", "react/jsx-runtime"],
},
},
});
78 changes: 65 additions & 13 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5174fd4

Please sign in to comment.