@dxos/react-hooks 0.6.12 → 0.6.13-main.548ca8d
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/dist/lib/browser/index.mjs +28 -26
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +26 -24
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +328 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/useAsyncEffect.test.d.ts +1 -1
- package/dist/types/src/useAsyncEffect.test.d.ts.map +1 -1
- package/dist/types/src/useAsyncState.d.ts +6 -0
- package/dist/types/src/useAsyncState.d.ts.map +1 -0
- package/dist/types/src/useControlledValue.d.ts +1 -1
- package/dist/types/src/useControlledValue.d.ts.map +1 -1
- package/dist/types/src/useDefaultValue.d.ts +1 -1
- package/dist/types/src/useDefaultValue.d.ts.map +1 -1
- package/dist/types/src/useMulticastObservable.test.d.ts +2 -0
- package/dist/types/src/useMulticastObservable.test.d.ts.map +1 -0
- package/dist/types/src/useTransitions.d.ts +1 -1
- package/dist/types/src/useTransitions.d.ts.map +1 -1
- package/package.json +8 -6
- package/src/index.ts +1 -1
- package/src/useAsyncEffect.test.tsx +3 -9
- package/src/{useAsyncCallback.ts → useAsyncState.ts} +7 -4
- package/src/useControlledValue.ts +5 -2
- package/src/useDefaultValue.ts +2 -2
- package/src/useMulticastObservable.test.tsx +23 -0
- package/src/useTransitions.ts +4 -7
- package/dist/types/src/useAsyncCallback.d.ts +0 -5
- package/dist/types/src/useAsyncCallback.d.ts.map +0 -1
|
@@ -2,14 +2,10 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import expect from 'expect';
|
|
6
|
-
import 'raf/polyfill';
|
|
7
5
|
import React, { useState } from 'react';
|
|
8
6
|
import { createRoot } from 'react-dom/client';
|
|
9
7
|
import { act } from 'react-dom/test-utils';
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
import { afterEach, beforeEach, describe, test } from '@dxos/test';
|
|
8
|
+
import { afterEach, beforeEach, describe, expect, test } from 'vitest';
|
|
13
9
|
|
|
14
10
|
import { useAsyncEffect } from './useAsyncEffect';
|
|
15
11
|
|
|
@@ -45,13 +41,11 @@ describe('useAsyncEffect', () => {
|
|
|
45
41
|
});
|
|
46
42
|
|
|
47
43
|
test('gets async value.', async () => {
|
|
48
|
-
|
|
44
|
+
await act(() => {
|
|
49
45
|
createRoot(rootContainer).render(<Test />);
|
|
50
46
|
});
|
|
51
47
|
|
|
52
48
|
const h1 = rootContainer.querySelector('h1');
|
|
53
|
-
|
|
54
|
-
expect(h1?.textContent).toEqual('DXOS');
|
|
55
|
-
});
|
|
49
|
+
expect(h1?.textContent).toEqual('DXOS');
|
|
56
50
|
});
|
|
57
51
|
});
|
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { useEffect, useState } from 'react';
|
|
5
|
+
import { type Dispatch, type SetStateAction, useEffect, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* NOTE: Use with care and when necessary to be able to cancel an async operation when unmounting.
|
|
9
9
|
*/
|
|
10
|
-
export const
|
|
10
|
+
export const useAsyncState = <T>(
|
|
11
|
+
cb: () => Promise<T | undefined>,
|
|
12
|
+
deps: any[] = [],
|
|
13
|
+
): [T | undefined, Dispatch<SetStateAction<T | undefined>>] => {
|
|
11
14
|
const [value, setValue] = useState<T | undefined>();
|
|
12
15
|
useEffect(() => {
|
|
13
16
|
const t = setTimeout(async () => {
|
|
@@ -16,7 +19,7 @@ export const useAsyncCallback = <T>(cb: () => Promise<T>): T | undefined => {
|
|
|
16
19
|
});
|
|
17
20
|
|
|
18
21
|
return () => clearTimeout(t);
|
|
19
|
-
},
|
|
22
|
+
}, deps);
|
|
20
23
|
|
|
21
|
-
return value;
|
|
24
|
+
return [value, setValue];
|
|
22
25
|
};
|
|
@@ -7,13 +7,16 @@ import { type Dispatch, type SetStateAction, useEffect, useState } from 'react';
|
|
|
7
7
|
/**
|
|
8
8
|
* A stateful hook with a controlled value.
|
|
9
9
|
*/
|
|
10
|
-
export const useControlledValue = <TValue>(
|
|
10
|
+
export const useControlledValue = <TValue>(
|
|
11
|
+
controlledValue: TValue,
|
|
12
|
+
...deps: any[]
|
|
13
|
+
): [TValue, Dispatch<SetStateAction<TValue>>] => {
|
|
11
14
|
const [value, setValue] = useState<TValue>(controlledValue);
|
|
12
15
|
useEffect(() => {
|
|
13
16
|
if (controlledValue !== undefined) {
|
|
14
17
|
setValue(controlledValue);
|
|
15
18
|
}
|
|
16
|
-
}, [controlledValue]);
|
|
19
|
+
}, [controlledValue, ...deps]);
|
|
17
20
|
|
|
18
21
|
return [value, setValue];
|
|
19
22
|
};
|
package/src/useDefaultValue.ts
CHANGED
|
@@ -15,11 +15,11 @@ import { useEffect, useState, useMemo } from 'react';
|
|
|
15
15
|
* @param defaultValue - The initial value used when the reactiveValue is undefined. This value is not reactive.
|
|
16
16
|
* @returns - The reactiveValue if it's defined, otherwise the defaultValue.
|
|
17
17
|
*/
|
|
18
|
-
export const useDefaultValue = <T>(reactiveValue: T | undefined | null,
|
|
18
|
+
export const useDefaultValue = <T>(reactiveValue: T | undefined | null, getDefaultValue: () => T): T => {
|
|
19
19
|
// Memoize defaultValue with an empty dependency array.
|
|
20
20
|
// This ensures that the defaultValue instance remains stable across all re-renders,
|
|
21
21
|
// regardless of whether the defaultValue changes.
|
|
22
|
-
const stableDefaultValue = useMemo(
|
|
22
|
+
const stableDefaultValue = useMemo(getDefaultValue, []);
|
|
23
23
|
const [value, setValue] = useState(reactiveValue ?? stableDefaultValue);
|
|
24
24
|
|
|
25
25
|
useEffect(() => {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2022 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { act, renderHook } from '@testing-library/react';
|
|
6
|
+
import { describe, expect, test } from 'vitest';
|
|
7
|
+
|
|
8
|
+
import { Event, MulticastObservable } from '@dxos/async';
|
|
9
|
+
|
|
10
|
+
import { useMulticastObservable } from './useMulticastObservable';
|
|
11
|
+
|
|
12
|
+
describe('useMulticastObservable', () => {
|
|
13
|
+
test('observes value', async () => {
|
|
14
|
+
const event = new Event<number>();
|
|
15
|
+
const observable = MulticastObservable.from(event, 0);
|
|
16
|
+
const { result } = renderHook(() => useMulticastObservable(observable));
|
|
17
|
+
expect(result.current).toEqual(0);
|
|
18
|
+
|
|
19
|
+
await act(() => event.emit(1));
|
|
20
|
+
|
|
21
|
+
await expect.poll(() => result.current).toEqual(1);
|
|
22
|
+
});
|
|
23
|
+
});
|
package/src/useTransitions.ts
CHANGED
|
@@ -28,21 +28,18 @@ export const useDidTransition = <T>(
|
|
|
28
28
|
|
|
29
29
|
useEffect(() => {
|
|
30
30
|
const toValueValid = isFunction<T>(toValue) ? toValue(currentValue) : toValue === currentValue;
|
|
31
|
-
|
|
32
31
|
const fromValueValid = isFunction<T>(fromValue)
|
|
33
32
|
? fromValue(previousValue.current)
|
|
34
33
|
: fromValue === previousValue.current;
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (transitioned) {
|
|
35
|
+
if (fromValueValid && toValueValid && !hasTransitioned) {
|
|
39
36
|
setHasTransitioned(true);
|
|
40
|
-
} else {
|
|
37
|
+
} else if ((!fromValueValid || !toValueValid) && hasTransitioned) {
|
|
41
38
|
setHasTransitioned(false);
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
previousValue.current = currentValue;
|
|
45
|
-
}, [currentValue, fromValue, toValue,
|
|
42
|
+
}, [currentValue, fromValue, toValue, hasTransitioned]);
|
|
46
43
|
|
|
47
44
|
return hasTransitioned;
|
|
48
45
|
};
|
|
@@ -55,7 +52,7 @@ export const useDidTransition = <T>(
|
|
|
55
52
|
export const useOnTransition = <T>(
|
|
56
53
|
currentValue: T,
|
|
57
54
|
fromValue: T | ((value: T) => boolean),
|
|
58
|
-
toValue: ((value: T) => boolean)
|
|
55
|
+
toValue: T | ((value: T) => boolean),
|
|
59
56
|
callback: () => void,
|
|
60
57
|
) => {
|
|
61
58
|
const dirty = useRef(false);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useAsyncCallback.d.ts","sourceRoot":"","sources":["../../../src/useAsyncCallback.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,MAAM,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,CAAC,GAAG,SAY9D,CAAC"}
|