extra-react-hooks 0.8.11 → 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,35 +25,21 @@ 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());
33
+ onChange(value, true);
35
34
  }
36
35
  }
37
36
  else {
38
- setDisplayValue(value.toString(), true);
37
+ setDisplayValue(value.toString());
38
+ onChange(value, true);
39
39
  }
40
40
  }
41
41
  };
42
42
  }
43
43
  };
44
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, force = false) => {
54
- if (force || stateRef.current !== newState) {
55
- stateRef.current = newState;
56
- forceUpdate();
57
- }
58
- }
59
- ];
60
- }
61
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,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;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;wBACzC,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAA;oBACzC,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.11",
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,12 +1,13 @@
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
8
6
  lazy?: boolean
9
7
 
8
+ /**
9
+ * @param isEnd 表示输入结束, 每次输入结束一定会产生一个`isEnd = true`的调用.
10
+ */
10
11
  onChange(value: number, isEnd: boolean): void
11
12
  }): {
12
13
  getInputProps(): Required<Pick<
@@ -23,8 +24,11 @@ export function useNumberInput({ value, lazy, onChange }: {
23
24
  getInputProps() {
24
25
  return {
25
26
  type: 'number'
27
+ // `input[type='number']`的特异行为:
28
+ // 如果设置的value与元素内部的值在数字上相同, 则界面不会发生更新.
29
+ // 要解决这个问题需要对DOM快速更新两次: 清空, 然后重新设置值, 不适用于React的受控组件模型.
26
30
  , value: displayValue
27
- // `input[type='number']`有一些特异行为:
31
+ // `input[type='number']`的特异行为:
28
32
  // 如果只是在数字后面输入点`.`, 不会触发change事件.
29
33
  , onChange(e) {
30
34
  if (lazy) {
@@ -46,40 +50,21 @@ export function useNumberInput({ value, lazy, onChange }: {
46
50
  const newValue = e.target.valueAsNumber
47
51
 
48
52
  if (isntNaN(newValue) && newValue !== value) {
49
- setDisplayValue(newValue.toString(), true)
53
+ setDisplayValue(newValue.toString())
50
54
 
51
55
  onChange(newValue, true)
52
56
  } else {
53
- setDisplayValue(value.toString(), true)
57
+ setDisplayValue(value.toString())
58
+
59
+ onChange(value, true)
54
60
  }
55
61
  } else {
56
- setDisplayValue(value.toString(), true)
62
+ setDisplayValue(value.toString())
63
+
64
+ onChange(value, true)
57
65
  }
58
66
  }
59
67
  }
60
68
  }
61
69
  }
62
70
  }
63
-
64
- function useDerivedState<T>(dep: T): [
65
- state: T
66
- , setState: (newState: T, force?: boolean) => void
67
- ] {
68
- const forceUpdate = useForceUpdate()
69
- const stateRef = useRef<T>(dep)
70
-
71
- useIIFE(() => {
72
- stateRef.current = dep
73
- }, [dep])
74
-
75
- return [
76
- stateRef.current
77
- , (newState, force = false) => {
78
- if (force || stateRef.current !== newState) {
79
- stateRef.current = newState
80
-
81
- forceUpdate()
82
- }
83
- }
84
- ]
85
- }