extra-react-hooks 0.8.12 → 0.8.13

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 CHANGED
@@ -249,3 +249,11 @@ function useNumberInput(params: {
249
249
  ```ts
250
250
  function useMediaQuery(query: string): boolean
251
251
  ```
252
+
253
+ ### useDerivedState
254
+ ```ts
255
+ function useDerivedState<T>(value: T): [
256
+ derivedState: T
257
+ , setDerivedState: (newDerivedState: T) => void
258
+ ]
259
+ ```
package/lib/index.d.ts CHANGED
@@ -26,3 +26,4 @@ export * from './use-isomorphic-layout-effect.js';
26
26
  export * from './use-debounce.js';
27
27
  export * from './use-number-input.js';
28
28
  export * from './use-media-query.js';
29
+ export * from './use-derived-state.js';
package/lib/index.js CHANGED
@@ -26,4 +26,5 @@ export * from './use-isomorphic-layout-effect.js';
26
26
  export * from './use-debounce.js';
27
27
  export * from './use-number-input.js';
28
28
  export * from './use-media-query.js';
29
+ export * from './use-derived-state.js';
29
30
  //# 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,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,0BAA0B,CAAA;AACxC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,kBAAkB,CAAA;AAChC,cAAc,mCAAmC,CAAA;AACjD,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,sBAAsB,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,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,0BAA0B,CAAA;AACxC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,kBAAkB,CAAA;AAChC,cAAc,mCAAmC,CAAA;AACjD,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA"}
@@ -0,0 +1,4 @@
1
+ export declare function useDerivedState<T>(value: T): [
2
+ derivedState: T,
3
+ setDerivedState: (newDerivedState: T) => void
4
+ ];
@@ -0,0 +1,20 @@
1
+ import { useRef, useCallback } from 'react';
2
+ import { useIIFE } from './use-iife.js';
3
+ import { useForceUpdate } from './use-force-update.js';
4
+ export function useDerivedState(value) {
5
+ const forceUpdate = useForceUpdate();
6
+ const stateRef = useRef(value);
7
+ useIIFE(() => {
8
+ stateRef.current = value;
9
+ }, [value]);
10
+ return [
11
+ stateRef.current,
12
+ useCallback(newState => {
13
+ if (stateRef.current !== newState) {
14
+ stateRef.current = newState;
15
+ forceUpdate();
16
+ }
17
+ }, [])
18
+ ];
19
+ }
20
+ //# sourceMappingURL=use-derived-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-derived-state.js","sourceRoot":"","sources":["../src/use-derived-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,MAAM,UAAU,eAAe,CAAI,KAAQ;IAIzC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IACpC,MAAM,QAAQ,GAAG,MAAM,CAAI,KAAK,CAAC,CAAA;IAEjC,OAAO,CAAC,GAAG,EAAE;QACX,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAA;IAC1B,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,OAAO;QACL,QAAQ,CAAC,OAAO;QAChB,WAAW,CAAC,QAAQ,CAAC,EAAE;YACrB,IAAI,QAAQ,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAClC,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAA;gBAE3B,WAAW,EAAE,CAAA;YACf,CAAC;QACH,CAAC,EAAE,EAAE,CAAC;KACP,CAAA;AACH,CAAC"}
@@ -1,7 +1,5 @@
1
- import { useRef } from 'react';
2
1
  import { isntNaN } from 'extra-utils';
3
- import { useIIFE } from './use-iife.js';
4
- import { useForceUpdate } from './use-force-update.js';
2
+ import { useDerivedState } from './use-derived-state.js';
5
3
  export function useNumberInput({ value, lazy, onChange }) {
6
4
  const [displayValue, setDisplayValue] = useDerivedState(value.toString());
7
5
  return {
@@ -27,16 +25,16 @@ export function useNumberInput({ value, lazy, onChange }) {
27
25
  if (e.target.checkValidity()) {
28
26
  const newValue = e.target.valueAsNumber;
29
27
  if (isntNaN(newValue) && newValue !== value) {
30
- setDisplayValue(newValue.toString(), true);
28
+ setDisplayValue(newValue.toString());
31
29
  onChange(newValue, true);
32
30
  }
33
31
  else {
34
- setDisplayValue(value.toString(), true);
32
+ setDisplayValue(value.toString());
35
33
  onChange(value, true);
36
34
  }
37
35
  }
38
36
  else {
39
- setDisplayValue(value.toString(), true);
37
+ setDisplayValue(value.toString());
40
38
  onChange(value, true);
41
39
  }
42
40
  }
@@ -44,20 +42,4 @@ export function useNumberInput({ value, lazy, onChange }) {
44
42
  }
45
43
  };
46
44
  }
47
- function useDerivedState(dep) {
48
- const forceUpdate = useForceUpdate();
49
- const stateRef = useRef(dep);
50
- useIIFE(() => {
51
- stateRef.current = dep;
52
- }, [dep]);
53
- return [
54
- stateRef.current,
55
- (newState, force = false) => {
56
- if (force || stateRef.current !== newState) {
57
- stateRef.current = newState;
58
- forceUpdate();
59
- }
60
- }
61
- ];
62
- }
63
45
  //# sourceMappingURL=use-number-input.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-number-input.js","sourceRoot":"","sources":["../src/use-number-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,MAAM,UAAU,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAQrD;IASC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,eAAe,CAAS,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;IAEjF,OAAO;QACL,aAAa;YACX,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,YAAY;gBAGnB,QAAQ,CAAC,CAAC;oBACR,IAAI,IAAI,EAAE,CAAC;wBACT,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,CAAA;wBAEzB,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;oBACjC,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,CAAC;4BAC9B,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,CAAA;4BAEvC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;gCAC5C,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;4BAC3B,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,MAAM,CAAC,CAAC;oBACN,IAAI,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,CAAC;wBAC7B,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,CAAA;wBAEvC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;4BAC5C,eAAe,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAA;4BAE1C,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;wBAC1B,CAAC;6BAAM,CAAC;4BACN,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAA;4BAEvC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;wBACvB,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAA;wBAEvC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;oBACvB,CAAC;gBACH,CAAC;aACF,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED,SAAS,eAAe,CAAI,GAAM;IAIhC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IACpC,MAAM,QAAQ,GAAG,MAAM,CAAI,GAAG,CAAC,CAAA;IAE/B,OAAO,CAAC,GAAG,EAAE;QACX,QAAQ,CAAC,OAAO,GAAG,GAAG,CAAA;IACxB,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IAET,OAAO;QACL,QAAQ,CAAC,OAAO;QAChB,CAAC,QAAQ,EAAE,KAAK,GAAG,KAAK,EAAE,EAAE;YAC1B,IAAI,KAAK,IAAI,QAAQ,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC3C,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAA;gBAE3B,WAAW,EAAE,CAAA;YACf,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"use-number-input.js","sourceRoot":"","sources":["../src/use-number-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,MAAM,UAAU,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAQrD;IASC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,eAAe,CAAS,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;IAEjF,OAAO;QACL,aAAa;YACX,OAAO;gBACL,IAAI,EAAE,QAAQ;gBAId,KAAK,EAAE,YAAY;gBAGnB,QAAQ,CAAC,CAAC;oBACR,IAAI,IAAI,EAAE,CAAC;wBACT,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,CAAA;wBAEzB,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;oBACjC,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,CAAC;4BAC9B,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,CAAA;4BAEvC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;gCAC5C,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;4BAC3B,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,MAAM,CAAC,CAAC;oBACN,IAAI,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,CAAC;wBAC7B,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,CAAA;wBAEvC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;4BAC5C,eAAe,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;4BAEpC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;wBAC1B,CAAC;6BAAM,CAAC;4BACN,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;4BAEjC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;wBACvB,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;wBAEjC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;oBACvB,CAAC;gBACH,CAAC;aACF,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "extra-react-hooks",
3
- "version": "0.8.12",
3
+ "version": "0.8.13",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "files": [
package/src/index.ts CHANGED
@@ -26,3 +26,4 @@ export * from './use-isomorphic-layout-effect.js'
26
26
  export * from './use-debounce.js'
27
27
  export * from './use-number-input.js'
28
28
  export * from './use-media-query.js'
29
+ export * from './use-derived-state.js'
@@ -0,0 +1,26 @@
1
+ import { useRef, useCallback } from 'react'
2
+ import { useIIFE } from './use-iife.js'
3
+ import { useForceUpdate } from './use-force-update.js'
4
+
5
+ export function useDerivedState<T>(value: T): [
6
+ derivedState: T
7
+ , setDerivedState: (newDerivedState: T) => void
8
+ ] {
9
+ const forceUpdate = useForceUpdate()
10
+ const stateRef = useRef<T>(value)
11
+
12
+ useIIFE(() => {
13
+ stateRef.current = value
14
+ }, [value])
15
+
16
+ return [
17
+ stateRef.current
18
+ , useCallback(newState => {
19
+ if (stateRef.current !== newState) {
20
+ stateRef.current = newState
21
+
22
+ forceUpdate()
23
+ }
24
+ }, [])
25
+ ]
26
+ }
@@ -1,7 +1,5 @@
1
- import { useRef } from 'react'
2
1
  import { isntNaN } from 'extra-utils'
3
- import { useIIFE } from './use-iife.js'
4
- import { useForceUpdate } from './use-force-update.js'
2
+ import { useDerivedState } from './use-derived-state.js'
5
3
 
6
4
  export function useNumberInput({ value, lazy, onChange }: {
7
5
  value: number
@@ -26,8 +24,11 @@ export function useNumberInput({ value, lazy, onChange }: {
26
24
  getInputProps() {
27
25
  return {
28
26
  type: 'number'
27
+ // `input[type='number']`的特异行为:
28
+ // 如果设置的value与元素内部的值在数字上相同, 则界面不会发生更新.
29
+ // 要解决这个问题需要对DOM快速更新两次: 清空, 然后重新设置值, 不适用于React的受控组件模型.
29
30
  , value: displayValue
30
- // `input[type='number']`有一些特异行为:
31
+ // `input[type='number']`的特异行为:
31
32
  // 如果只是在数字后面输入点`.`, 不会触发change事件.
32
33
  , onChange(e) {
33
34
  if (lazy) {
@@ -49,16 +50,16 @@ export function useNumberInput({ value, lazy, onChange }: {
49
50
  const newValue = e.target.valueAsNumber
50
51
 
51
52
  if (isntNaN(newValue) && newValue !== value) {
52
- setDisplayValue(newValue.toString(), true)
53
+ setDisplayValue(newValue.toString())
53
54
 
54
55
  onChange(newValue, true)
55
56
  } else {
56
- setDisplayValue(value.toString(), true)
57
+ setDisplayValue(value.toString())
57
58
 
58
59
  onChange(value, true)
59
60
  }
60
61
  } else {
61
- setDisplayValue(value.toString(), true)
62
+ setDisplayValue(value.toString())
62
63
 
63
64
  onChange(value, true)
64
65
  }
@@ -67,26 +68,3 @@ export function useNumberInput({ value, lazy, onChange }: {
67
68
  }
68
69
  }
69
70
  }
70
-
71
- function useDerivedState<T>(dep: T): [
72
- state: T
73
- , setState: (newState: T, force?: boolean) => void
74
- ] {
75
- const forceUpdate = useForceUpdate()
76
- const stateRef = useRef<T>(dep)
77
-
78
- useIIFE(() => {
79
- stateRef.current = dep
80
- }, [dep])
81
-
82
- return [
83
- stateRef.current
84
- , (newState, force = false) => {
85
- if (force || stateRef.current !== newState) {
86
- stateRef.current = newState
87
-
88
- forceUpdate()
89
- }
90
- }
91
- ]
92
- }