extra-react-hooks 0.8.9 → 0.8.10

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.
@@ -1,29 +1,21 @@
1
- import { useState } from 'react';
1
+ import { useRef } from 'react';
2
2
  import { isntNaN } from 'extra-utils';
3
3
  import { useIIFE } from './use-iife.js';
4
+ import { useForceUpdate } from './use-force-update.js';
4
5
  export function useNumberInput({ value, lazy, onChange }) {
5
- const [displayValue, setDisplayValue] = useState(() => value.toString());
6
- useIIFE(() => {
7
- if (!lazy) {
8
- const oldValue = Number(displayValue);
9
- if (oldValue !== value)
10
- setDisplayValue(value.toString());
11
- }
12
- }, [lazy, value, displayValue]);
13
- useIIFE(() => {
14
- if (lazy) {
15
- setDisplayValue(value.toString());
16
- }
17
- }, [lazy, value]);
6
+ const [displayValue, setDisplayValue] = useDerivedState(value.toString());
18
7
  return {
19
8
  getInputProps() {
20
9
  return {
21
10
  type: 'number',
22
11
  value: displayValue,
23
12
  onChange(e) {
24
- setDisplayValue(e.target.value);
25
- if (e.target.reportValidity()) {
26
- if (!lazy) {
13
+ if (lazy) {
14
+ e.target.reportValidity();
15
+ setDisplayValue(e.target.value);
16
+ }
17
+ else {
18
+ if (e.target.reportValidity()) {
27
19
  const newValue = e.target.valueAsNumber;
28
20
  if (isntNaN(newValue) && newValue !== value) {
29
21
  onChange(newValue, false);
@@ -34,23 +26,36 @@ export function useNumberInput({ value, lazy, onChange }) {
34
26
  onBlur(e) {
35
27
  if (e.target.checkValidity()) {
36
28
  const newValue = e.target.valueAsNumber;
37
- if (!lazy || (isntNaN(newValue) && newValue !== value)) {
38
- onChange(newValue, true);
29
+ if (isntNaN(newValue) && newValue !== value) {
39
30
  setDisplayValue(newValue.toString());
40
- return;
31
+ onChange(newValue, true);
41
32
  }
42
- }
43
- else {
44
- if (!lazy) {
45
- onChange(value, true);
33
+ else {
46
34
  setDisplayValue(value.toString());
47
- return;
48
35
  }
49
36
  }
50
- setDisplayValue(value.toString());
37
+ else {
38
+ setDisplayValue(value.toString());
39
+ }
51
40
  }
52
41
  };
53
42
  }
54
43
  };
55
44
  }
45
+ function useDerivedState(dep) {
46
+ const forceUpdate = useForceUpdate();
47
+ const stateRef = useRef(dep);
48
+ useIIFE(() => {
49
+ stateRef.current = dep;
50
+ }, [dep]);
51
+ return [
52
+ stateRef.current,
53
+ newState => {
54
+ if (stateRef.current !== newState) {
55
+ stateRef.current = newState;
56
+ forceUpdate();
57
+ }
58
+ }
59
+ ];
60
+ }
56
61
  //# 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,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,MAAM,UAAU,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAKrD;IASC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAS,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;IAEhF,OAAO,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;YAGrC,IAAI,QAAQ,KAAK,KAAK;gBAAE,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC3D,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAA;IAE/B,OAAO,CAAC,GAAG,EAAE;QACX,IAAI,IAAI,EAAE,CAAC;YAGT,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;QACnC,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;IAEjB,OAAO;QACL,aAAa;YACX,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,YAAY;gBACnB,QAAQ,CAAC,CAAC;oBACR,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;oBAE/B,IAAI,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,CAAC;wBAC9B,IAAI,CAAC,IAAI,EAAE,CAAC;4BACV,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,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,KAAK,CAAC,EAAE,CAAC;4BACvD,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;4BAIxB,eAAe,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;4BAEpC,OAAM;wBACR,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,IAAI,EAAE,CAAC;4BACV,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;4BAErB,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;4BAEjC,OAAM;wBACR,CAAC;oBACH,CAAC;oBAGD,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;gBACnC,CAAC;aACF,CAAA;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,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,EAKrD;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;gBACnB,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;wBACnC,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;oBACnC,CAAC;gBACH,CAAC;aACF,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED,SAAS,eAAe,CAAI,GAAM;IAChC,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,QAAQ,CAAC,EAAE;YACT,IAAI,QAAQ,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAClC,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAA;gBAE3B,WAAW,EAAE,CAAA;YACf,CAAC;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.9",
3
+ "version": "0.8.10",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "files": [
@@ -1,6 +1,7 @@
1
- import { useState } from 'react'
1
+ import { useRef } from 'react'
2
2
  import { isntNaN } from 'extra-utils'
3
3
  import { useIIFE } from './use-iife.js'
4
+ import { useForceUpdate } from './use-force-update.js'
4
5
 
5
6
  export function useNumberInput({ value, lazy, onChange }: {
6
7
  value: number
@@ -16,24 +17,7 @@ export function useNumberInput({ value, lazy, onChange }: {
16
17
  | 'onBlur'
17
18
  >>
18
19
  } {
19
- const [displayValue, setDisplayValue] = useState<string>(() => value.toString())
20
-
21
- useIIFE(() => {
22
- if (!lazy) {
23
- const oldValue = Number(displayValue)
24
-
25
- // 以传入的值为准, 但只有在实际代表的值不同时, 才更新.
26
- if (oldValue !== value) setDisplayValue(value.toString())
27
- }
28
- }, [lazy, value, displayValue])
29
-
30
- useIIFE(() => {
31
- if (lazy) {
32
- // 以传入的值为准.
33
- // 由于onChange是惰性调用, 不需要检查值的相等性.
34
- setDisplayValue(value.toString())
35
- }
36
- }, [lazy, value])
20
+ const [displayValue, setDisplayValue] = useDerivedState<string>(value.toString())
37
21
 
38
22
  return {
39
23
  getInputProps() {
@@ -41,10 +25,12 @@ export function useNumberInput({ value, lazy, onChange }: {
41
25
  type: 'number'
42
26
  , value: displayValue
43
27
  , onChange(e) {
44
- setDisplayValue(e.target.value)
28
+ if (lazy) {
29
+ e.target.reportValidity()
45
30
 
46
- if (e.target.reportValidity()) {
47
- if (!lazy) {
31
+ setDisplayValue(e.target.value)
32
+ } else {
33
+ if (e.target.reportValidity()) {
48
34
  const newValue = e.target.valueAsNumber
49
35
 
50
36
  if (isntNaN(newValue) && newValue !== value) {
@@ -57,29 +43,38 @@ export function useNumberInput({ value, lazy, onChange }: {
57
43
  if (e.target.checkValidity()) {
58
44
  const newValue = e.target.valueAsNumber
59
45
 
60
- if (!lazy || (isntNaN(newValue) && newValue !== value)) {
61
- onChange(newValue, true)
62
-
63
- // 使用格式化后的新值.
64
- // 若hook的调用方决定不接受新值, 则displayValue的值会被覆盖.
46
+ if (isntNaN(newValue) && newValue !== value) {
65
47
  setDisplayValue(newValue.toString())
66
48
 
67
- return
68
- }
69
- } else {
70
- if (!lazy) {
71
- onChange(value, true)
72
-
49
+ onChange(newValue, true)
50
+ } else {
73
51
  setDisplayValue(value.toString())
74
-
75
- return
76
52
  }
53
+ } else {
54
+ setDisplayValue(value.toString())
77
55
  }
78
-
79
- // 继续使用旧值, 但对旧值格式化.
80
- setDisplayValue(value.toString())
81
56
  }
82
57
  }
83
58
  }
84
59
  }
85
60
  }
61
+
62
+ function useDerivedState<T>(dep: T): [state: T, setState: (newState: T) => void] {
63
+ const forceUpdate = useForceUpdate()
64
+ const stateRef = useRef<T>(dep)
65
+
66
+ useIIFE(() => {
67
+ stateRef.current = dep
68
+ }, [dep])
69
+
70
+ return [
71
+ stateRef.current
72
+ , newState => {
73
+ if (stateRef.current !== newState) {
74
+ stateRef.current = newState
75
+
76
+ forceUpdate()
77
+ }
78
+ }
79
+ ]
80
+ }