Skip to content

Commit 226eb9d

Browse files
author
John Chipps-Harding
committed
Fix tests
1 parent c6ecbcc commit 226eb9d

File tree

2 files changed

+27
-36
lines changed

2 files changed

+27
-36
lines changed

src/index.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,25 @@ import { SUPPORTED } from "./utils";
55
const useLocalState = <T>(
66
key: string,
77
defaultValue: T
8-
): [T, (newValue: T) => void] => {
8+
): [T, (v: T | ((v: T) => T)) => void] => {
99
const [value, setValue] = useState<T>(() => {
10-
if (!SUPPORTED) return defaultValue;
10+
const toStore =
11+
typeof defaultValue === "function" ? defaultValue() : defaultValue;
12+
if (!SUPPORTED) return toStore;
1113
const item = window.localStorage.getItem(key);
12-
return item ? JSON.parse(item) : defaultValue;
14+
try {
15+
return item ? JSON.parse(item) : toStore;
16+
} catch (error) {
17+
return toStore;
18+
}
1319
});
1420

15-
const setLocalStateValue = (newValue: T) => {
16-
if (SUPPORTED) window.localStorage.setItem(key, JSON.stringify(newValue));
17-
setValue(newValue);
21+
const setLocalStateValue = (newValue: T | ((v: T) => T)) => {
22+
const isCallable = (value: unknown): value is (v: T) => T =>
23+
typeof value === "function";
24+
const toStore = isCallable(newValue) ? newValue(value) : newValue;
25+
if (SUPPORTED) window.localStorage.setItem(key, JSON.stringify(toStore));
26+
setValue(toStore);
1827
};
1928

2029
return [value, setLocalStateValue];

test/index.test.tsx

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -119,21 +119,21 @@ describe("useLocalState()", () => {
119119
});
120120

121121
// todo(): this logic could be super handy...
122-
// it("updates state with callback function", () => {
123-
// const key = "todos";
124-
// const values = ["first", "second"];
125-
// const { result } = renderHook(() => useLocalState(key, values));
122+
it("updates state with callback function", () => {
123+
const key = "todos";
124+
const values = ["first", "second"];
125+
const { result } = renderHook(() => useLocalState(key, values));
126126

127-
// const newValues = ["first", "second"];
128-
// act(() => {
129-
// const setTodos = result.current[1];
127+
const newValues = ["first", "second"];
128+
act(() => {
129+
const setTodos = result.current[1];
130130

131-
// setTodos((current) => [...current, ...newValues]);
132-
// });
131+
setTodos((current) => [...current, ...newValues]);
132+
});
133133

134-
// const [todos] = result.current;
135-
// expect(todos).toEqual([...values, ...newValues]);
136-
// });
134+
const [todos] = result.current;
135+
expect(todos).toEqual([...values, ...newValues]);
136+
});
137137

138138
it("does not fail even if invalid data is stored into localStorage", async () => {
139139
if (!SUPPORTED) return;
@@ -165,24 +165,6 @@ describe("useLocalState()", () => {
165165
expect(todos).toEqual(values);
166166
});
167167

168-
it("throws an error on two states with the same key", async () => {
169-
const consoleError = console.error;
170-
console.error = () => null;
171-
172-
const key = "todos";
173-
const valuesA = ["first", "second"];
174-
const valuesB = ["third", "fourth"];
175-
176-
expect(() => {
177-
renderHook(() => {
178-
useLocalState(key, valuesA);
179-
useLocalState(key, valuesB);
180-
});
181-
}).toThrow();
182-
183-
console.error = consoleError;
184-
});
185-
186168
it("does not throw an error with two states with different keys", async () => {
187169
const keyA = "todos";
188170
const keyB = "todos";

0 commit comments

Comments
 (0)