extra-react-hooks 0.6.1 → 0.6.3

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/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.6.3](https://github.com/BlackGlory/extra-react-hooks/compare/v0.6.2...v0.6.3) (2023-06-13)
6
+
7
+
8
+ ### Features
9
+
10
+ * add `useMemoWithCleanup`, `useGetSet` ([9ed180b](https://github.com/BlackGlory/extra-react-hooks/commit/9ed180be34e193371ea6c2beb3adcf2e6ce6356c))
11
+
12
+ ### [0.6.2](https://github.com/BlackGlory/extra-react-hooks/compare/v0.6.1...v0.6.2) (2023-06-13)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * **useCallbackAsync:** replace useEffect with useLayoutEffect ([8f8f5f5](https://github.com/BlackGlory/extra-react-hooks/commit/8f8f5f511444bd30132e9eadb781a1a72ccbacb3))
18
+
5
19
  ### [0.6.1](https://github.com/BlackGlory/extra-react-hooks/compare/v0.6.0...v0.6.1) (2023-06-13)
6
20
 
7
21
 
package/README.md CHANGED
@@ -150,3 +150,19 @@ function useRenderCounter(): number
150
150
  ```ts
151
151
  function useIIFE(iife: () => void, deps: React.DependencyList): void
152
152
  ```
153
+
154
+ ### useMemoWithCleanup
155
+ ```ts
156
+ function useMemoWithCleanup<T>(
157
+ factory: () => T
158
+ , cleanup: (value: T) => void
159
+ , deps?: React.DependencyList
160
+ ): T
161
+ ```
162
+
163
+ ### useGetSet
164
+ ```ts
165
+ function useGetSet<T>(
166
+ initialValue: T
167
+ ): [get: () => T, set: (value: T) => void]
168
+ ```
package/lib/index.d.ts CHANGED
@@ -17,3 +17,5 @@ export * from './use-step.js';
17
17
  export * from './use-force-update.js';
18
18
  export * from './use-finite-state-machine.js';
19
19
  export * from './use-iife.js';
20
+ export * from './use-memo-with-cleanup.js';
21
+ export * from './use-get-set.js';
package/lib/index.js CHANGED
@@ -17,4 +17,6 @@ export * from './use-step.js';
17
17
  export * from './use-force-update.js';
18
18
  export * from './use-finite-state-machine.js';
19
19
  export * from './use-iife.js';
20
+ export * from './use-memo-with-cleanup.js';
21
+ export * from './use-get-set.js';
20
22
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,yBAAyB,CAAA;AACvC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,sBAAsB,CAAA;AACpC,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,0BAA0B,CAAA;AACxC,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,eAAe,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,yBAAyB,CAAA;AACvC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,sBAAsB,CAAA;AACpC,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,0BAA0B,CAAA;AACxC,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,eAAe,CAAA;AAC7B,cAAc,4BAA4B,CAAA;AAC1C,cAAc,kBAAkB,CAAA"}
@@ -1,20 +1,20 @@
1
- import { useEffect, useCallback, useMemo } from 'react';
1
+ import { useCallback } from 'react';
2
2
  import { go } from '@blackglory/prelude';
3
3
  import { AbortController } from 'extra-abort';
4
- const abort = Symbol();
4
+ import { useMemoWithCleanup } from './use-memo-with-cleanup.js';
5
+ const symbolAbort = Symbol();
5
6
  export function useCallbackAsync(callback, deps) {
6
- const controller = useMemo(() => new AbortController(), deps);
7
- useEffect(() => () => controller.abort(abort), [controller]);
7
+ const controller = useMemoWithCleanup(() => new AbortController(), controller => controller.abort(symbolAbort), deps);
8
8
  return useCallback((...args) => {
9
9
  go(async () => {
10
10
  try {
11
11
  await callback(...args, controller.signal);
12
12
  }
13
13
  catch (err) {
14
- if (err !== abort)
14
+ if (err !== symbolAbort)
15
15
  throw err;
16
16
  }
17
17
  });
18
- }, [controller]);
18
+ }, deps);
19
19
  }
20
20
  //# sourceMappingURL=use-callback-async.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-callback-async.js","sourceRoot":"","sources":["../src/use-callback-async.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAA;AACvE,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C,MAAM,KAAK,GAAG,MAAM,EAAE,CAAA;AAEtB,MAAM,UAAU,gBAAgB,CAC9B,QAA0E,EAC1E,IAAoB;IAEpB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,eAAe,EAAE,EAAE,IAAI,CAAC,CAAA;IAC7D,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;IAE5D,OAAO,WAAW,CAAC,CAAC,GAAG,IAAU,EAAE,EAAE;QACnC,EAAE,CAAC,KAAK,IAAI,EAAE;YACZ,IAAI;gBACF,MAAM,QAAQ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;aAC3C;YAAC,OAAO,GAAG,EAAE;gBACZ,IAAI,GAAG,KAAK,KAAK;oBAAE,MAAM,GAAG,CAAA;aAC7B;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;AAClB,CAAC"}
1
+ {"version":3,"file":"use-callback-async.js","sourceRoot":"","sources":["../src/use-callback-async.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,OAAO,CAAA;AACnD,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAE/D,MAAM,WAAW,GAAG,MAAM,EAAE,CAAA;AAE5B,MAAM,UAAU,gBAAgB,CAC9B,QAA0E,EAC1E,IAAoB;IAEpB,MAAM,UAAU,GAAG,kBAAkB,CACnC,GAAG,EAAE,CAAC,IAAI,eAAe,EAAE,EAC3B,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,EAC3C,IAAI,CACL,CAAA;IAED,OAAO,WAAW,CAAC,CAAC,GAAG,IAAU,EAAE,EAAE;QACnC,EAAE,CAAC,KAAK,IAAI,EAAE;YACZ,IAAI;gBACF,MAAM,QAAQ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;aAC3C;YAAC,OAAO,GAAG,EAAE;gBACZ,IAAI,GAAG,KAAK,WAAW;oBAAE,MAAM,GAAG,CAAA;aACnC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,EAAE,IAAI,CAAC,CAAA;AACV,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function useGetSet<T>(initialValue: T): [get: () => T, set: (value: T) => void];
@@ -0,0 +1,16 @@
1
+ import { useRef, useCallback } from 'react';
2
+ import { useForceUpdate } from './use-force-update.js';
3
+ export function useGetSet(initialValue) {
4
+ const forceUpdate = useForceUpdate();
5
+ const ref = useRef(initialValue);
6
+ return [
7
+ useCallback(() => ref.current, []),
8
+ useCallback((value) => {
9
+ if (ref.current !== value) {
10
+ ref.current = value;
11
+ forceUpdate();
12
+ }
13
+ }, [])
14
+ ];
15
+ }
16
+ //# sourceMappingURL=use-get-set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-get-set.js","sourceRoot":"","sources":["../src/use-get-set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,MAAM,UAAU,SAAS,CACvB,YAAe;IAEf,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IACpC,MAAM,GAAG,GAAG,MAAM,CAAI,YAAY,CAAC,CAAA;IAEnC,OAAO;QACL,WAAW,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;QAClC,WAAW,CAAC,CAAC,KAAQ,EAAE,EAAE;YACvB,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,EAAE;gBACzB,GAAG,CAAC,OAAO,GAAG,KAAK,CAAA;gBACnB,WAAW,EAAE,CAAA;aACd;QACH,CAAC,EAAE,EAAE,CAAC;KACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare function useMemoWithCleanup<T>(factory: () => T, cleanup: (value: T) => void, deps?: React.DependencyList): T;
@@ -0,0 +1,9 @@
1
+ import { useMemo, useEffect } from 'react';
2
+ export function useMemoWithCleanup(factory, cleanup, deps) {
3
+ const value = useMemo(factory, deps);
4
+ useEffect(() => {
5
+ return () => cleanup(value);
6
+ }, deps);
7
+ return value;
8
+ }
9
+ //# sourceMappingURL=use-memo-with-cleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-memo-with-cleanup.js","sourceRoot":"","sources":["../src/use-memo-with-cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAE1C,MAAM,UAAU,kBAAkB,CAChC,OAAgB,EAChB,OAA2B,EAC3B,IAA2B;IAE3B,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAEpC,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC,EAAE,IAAI,CAAC,CAAA;IAER,OAAO,KAAK,CAAA;AACd,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "extra-react-hooks",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "files": [
package/src/index.ts CHANGED
@@ -17,3 +17,5 @@ export * from './use-step.js'
17
17
  export * from './use-force-update.js'
18
18
  export * from './use-finite-state-machine.js'
19
19
  export * from './use-iife.js'
20
+ export * from './use-memo-with-cleanup.js'
21
+ export * from './use-get-set.js'
@@ -1,23 +1,27 @@
1
- import { useEffect, useCallback, useMemo, DependencyList } from 'react'
1
+ import { useCallback, DependencyList } from 'react'
2
2
  import { go } from '@blackglory/prelude'
3
3
  import { AbortController } from 'extra-abort'
4
+ import { useMemoWithCleanup } from './use-memo-with-cleanup.js'
4
5
 
5
- const abort = Symbol()
6
+ const symbolAbort = Symbol()
6
7
 
7
8
  export function useCallbackAsync<Args extends unknown[]>(
8
9
  callback: (...args: [...args: Args, signal: AbortSignal]) => Promise<void>
9
10
  , deps: DependencyList
10
11
  ): (...args: Args) => void {
11
- const controller = useMemo(() => new AbortController(), deps)
12
- useEffect(() => () => controller.abort(abort), [controller])
12
+ const controller = useMemoWithCleanup(
13
+ () => new AbortController()
14
+ , controller => controller.abort(symbolAbort)
15
+ , deps
16
+ )
13
17
 
14
18
  return useCallback((...args: Args) => {
15
19
  go(async () => {
16
20
  try {
17
21
  await callback(...args, controller.signal)
18
22
  } catch (err) {
19
- if (err !== abort) throw err
23
+ if (err !== symbolAbort) throw err
20
24
  }
21
25
  })
22
- }, [controller])
26
+ }, deps)
23
27
  }
@@ -0,0 +1,19 @@
1
+ import { useRef, useCallback } from 'react'
2
+ import { useForceUpdate } from './use-force-update.js'
3
+
4
+ export function useGetSet<T>(
5
+ initialValue: T
6
+ ): [get: () => T, set: (value: T) => void] {
7
+ const forceUpdate = useForceUpdate()
8
+ const ref = useRef<T>(initialValue)
9
+
10
+ return [
11
+ useCallback(() => ref.current, [])
12
+ , useCallback((value: T) => {
13
+ if (ref.current !== value) {
14
+ ref.current = value
15
+ forceUpdate()
16
+ }
17
+ }, [])
18
+ ]
19
+ }
@@ -0,0 +1,15 @@
1
+ import { useMemo, useEffect } from 'react'
2
+
3
+ export function useMemoWithCleanup<T>(
4
+ factory: () => T
5
+ , cleanup: (value: T) => void
6
+ , deps?: React.DependencyList
7
+ ): T {
8
+ const value = useMemo(factory, deps)
9
+
10
+ useEffect(() => {
11
+ return () => cleanup(value)
12
+ }, deps)
13
+
14
+ return value
15
+ }