use-good-hooks 1.0.9 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -0
- package/dist/index.d.ts +48 -12
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -274,6 +274,94 @@ const ProductFilter = () => {
|
|
|
274
274
|
- State value
|
|
275
275
|
- State setter function
|
|
276
276
|
|
|
277
|
+
### `useGlobalState` and `createGlobalState`
|
|
278
|
+
|
|
279
|
+
Creates and manages global state that can be shared across components with automatic synchronization.
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import { createGlobalState, useGlobalState } from 'use-good-hooks';
|
|
283
|
+
|
|
284
|
+
// Create a global state instance (typically in a separate file)
|
|
285
|
+
const counterState = createGlobalState({ count: 0 });
|
|
286
|
+
|
|
287
|
+
// Component A
|
|
288
|
+
const CounterDisplay = () => {
|
|
289
|
+
const [counter, setCounter] = useGlobalState(counterState);
|
|
290
|
+
|
|
291
|
+
return (
|
|
292
|
+
<div>
|
|
293
|
+
<p>Count: {counter.count}</p>
|
|
294
|
+
<button onClick={() => setCounter({ count: counter.count + 1 })}>
|
|
295
|
+
Increment
|
|
296
|
+
</button>
|
|
297
|
+
</div>
|
|
298
|
+
);
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
// Component B (in a different part of your app)
|
|
302
|
+
const CounterActions = () => {
|
|
303
|
+
const [counter, setCounter] = useGlobalState(counterState);
|
|
304
|
+
|
|
305
|
+
return (
|
|
306
|
+
<div>
|
|
307
|
+
<button onClick={() => setCounter({ count: 0 })}>
|
|
308
|
+
Reset Count
|
|
309
|
+
</button>
|
|
310
|
+
<button onClick={() => setCounter(prev => ({ count: prev.count + 5 }))}>
|
|
311
|
+
Add 5
|
|
312
|
+
</button>
|
|
313
|
+
</div>
|
|
314
|
+
);
|
|
315
|
+
};
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
#### Usage
|
|
319
|
+
|
|
320
|
+
1. First, create a global state store:
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
// state/counter.ts
|
|
324
|
+
import { createGlobalState } from 'use-good-hooks';
|
|
325
|
+
|
|
326
|
+
export const counterState = createGlobalState({ count: 0 });
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
2. Then use it in any component:
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
import { useGlobalState } from 'use-good-hooks';
|
|
333
|
+
import { counterState } from './state/counter';
|
|
334
|
+
|
|
335
|
+
const MyComponent = () => {
|
|
336
|
+
const [counter, setCounter] = useGlobalState(counterState);
|
|
337
|
+
// ...
|
|
338
|
+
};
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
#### `createGlobalState` Parameters
|
|
342
|
+
|
|
343
|
+
- `initialState`: The initial state value
|
|
344
|
+
|
|
345
|
+
#### `createGlobalState` Returns
|
|
346
|
+
|
|
347
|
+
- Array with:
|
|
348
|
+
- `state`: The current state
|
|
349
|
+
- `setState`: Function to update state
|
|
350
|
+
- `store`: Object with utility methods:
|
|
351
|
+
- `getState()`: Function to get current state
|
|
352
|
+
- `subscribe(callback)`: Subscribe to state changes
|
|
353
|
+
- `resetState()`: Reset to initial state
|
|
354
|
+
|
|
355
|
+
#### `useGlobalState` Parameters
|
|
356
|
+
|
|
357
|
+
- `globalState`: The global state created with `createGlobalState`
|
|
358
|
+
|
|
359
|
+
#### `useGlobalState` Returns
|
|
360
|
+
|
|
361
|
+
- Array with:
|
|
362
|
+
- `state`: The component's local copy of the state
|
|
363
|
+
- `setState`: Function to update global state (accepts new value or update function)
|
|
364
|
+
|
|
277
365
|
## 🧪 Running Tests
|
|
278
366
|
|
|
279
367
|
This library is thoroughly tested with Vitest and React Testing Library. To run the tests:
|
package/dist/index.d.ts
CHANGED
|
@@ -1,20 +1,56 @@
|
|
|
1
|
-
|
|
2
|
-
import { default as useDistinct } from './hooks/use-distinct';
|
|
3
|
-
import { default as usePrev } from './hooks/use-prev';
|
|
4
|
-
import { default as useStorageState } from './hooks/use-storage-state';
|
|
5
|
-
import { default as useThrottle } from './hooks/use-throttle';
|
|
6
|
-
import { default as useUrlState } from './hooks/use-url-state';
|
|
1
|
+
declare type SetUrlStateAction<T> = T | ((prevState: T) => T);
|
|
7
2
|
|
|
8
|
-
|
|
3
|
+
declare type StorageType = 'local' | 'session';
|
|
9
4
|
|
|
10
|
-
|
|
5
|
+
declare type StrictObject = {
|
|
6
|
+
[key: string]: any;
|
|
7
|
+
} & {
|
|
8
|
+
length?: never;
|
|
9
|
+
};
|
|
11
10
|
|
|
12
|
-
export
|
|
11
|
+
export declare const useDebounce: <T>(value: T, delay?: number) => T;
|
|
13
12
|
|
|
14
|
-
export
|
|
13
|
+
export declare const useDistinct: <T>(inputValue: T, options?: UseDistinctOptions) => UseDistinctReturn<T>;
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
declare type UseDistinctOptions = {
|
|
16
|
+
compare?: (a: any, b: any) => boolean;
|
|
17
|
+
debounce?: number;
|
|
18
|
+
deep?: boolean;
|
|
19
|
+
};
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
declare type UseDistinctReturn<T> = {
|
|
22
|
+
distinct: boolean;
|
|
23
|
+
prevValue: T | undefined;
|
|
24
|
+
value: T;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export declare const usePrev: <T>(value: T) => T | undefined;
|
|
28
|
+
|
|
29
|
+
export declare const useStorageState: <T extends StrictObject>(key: string, initialState: T, options?: UseStorageStateOptions) => [T, (value: T | ((prev: T) => T)) => void, {
|
|
30
|
+
removeKey: () => void;
|
|
31
|
+
}];
|
|
32
|
+
|
|
33
|
+
declare type UseStorageStateOptions = {
|
|
34
|
+
debounce?: number;
|
|
35
|
+
onError?: (err: Error) => void;
|
|
36
|
+
omitKeys?: string[] | ((value: any, key: string) => boolean);
|
|
37
|
+
pickKeys?: string[] | ((value: any, key: string) => boolean);
|
|
38
|
+
storage?: StorageType;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export declare const useThrottle: <T>(value: T, delay?: number) => T;
|
|
42
|
+
|
|
43
|
+
export declare const useUrlState: <T extends StrictObject>(initialState: T, options: UseUrlStateOptions) => [T, (value: SetUrlStateAction<T>) => void];
|
|
44
|
+
|
|
45
|
+
declare type UseUrlStateOptions = {
|
|
46
|
+
debounce?: number;
|
|
47
|
+
kebabCase?: boolean;
|
|
48
|
+
omitKeys?: string[] | ((value: any, key: string) => boolean);
|
|
49
|
+
omitValues?: any[] | ((value: any, key: string) => boolean);
|
|
50
|
+
onError?: (err: Error) => void;
|
|
51
|
+
pickKeys?: string[] | ((value: any, key: string) => boolean);
|
|
52
|
+
prefix?: string;
|
|
53
|
+
url: URL;
|
|
54
|
+
};
|
|
19
55
|
|
|
20
56
|
export { }
|
package/package.json
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"@types/react": "^19.0.8",
|
|
15
15
|
"@types/react-dom": "^19.0.3",
|
|
16
16
|
"@vitejs/plugin-react": "^4.3.4",
|
|
17
|
+
"@vitest/coverage-v8": "3.0.7",
|
|
17
18
|
"clsx": "^2.1.1",
|
|
18
19
|
"eslint": "^9.19.0",
|
|
19
20
|
"eslint-plugin-react-hooks": "^5.0.0",
|
|
@@ -43,7 +44,8 @@
|
|
|
43
44
|
"build": "yarn lint && vite build --mode export",
|
|
44
45
|
"lint": "prettier --write . && eslint .",
|
|
45
46
|
"npm-publish": "yarn test --run && yarn build && yarn version --patch --no-git-tag-version && yarn publish --non-interactive",
|
|
46
|
-
"test": "vitest"
|
|
47
|
+
"test": "vitest",
|
|
48
|
+
"test:coverage": "vitest --coverage"
|
|
47
49
|
},
|
|
48
|
-
"version": "1.0.
|
|
50
|
+
"version": "1.0.11"
|
|
49
51
|
}
|