@dxos/react-async 2.28.2
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 +29 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +23 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/useAsyncEffect.d.ts +28 -0
- package/dist/src/useAsyncEffect.d.ts.map +1 -0
- package/dist/src/useAsyncEffect.js +53 -0
- package/dist/src/useAsyncEffect.js.map +1 -0
- package/dist/src/useAsyncEffect.test.d.ts +2 -0
- package/dist/src/useAsyncEffect.test.d.ts.map +1 -0
- package/dist/src/useAsyncEffect.test.js +70 -0
- package/dist/src/useAsyncEffect.test.js.map +1 -0
- package/dist/src/useControlledState.d.ts +17 -0
- package/dist/src/useControlledState.d.ts.map +1 -0
- package/dist/src/useControlledState.js +37 -0
- package/dist/src/useControlledState.js.map +1 -0
- package/dist/src/useDynamicRef.d.ts +17 -0
- package/dist/src/useDynamicRef.d.ts.map +1 -0
- package/dist/src/useDynamicRef.js +33 -0
- package/dist/src/useDynamicRef.js.map +1 -0
- package/dist/src/useMounted.d.ts +25 -0
- package/dist/src/useMounted.d.ts.map +1 -0
- package/dist/src/useMounted.js +42 -0
- package/dist/src/useMounted.js.map +1 -0
- package/dist/src/useStateUpdater.d.ts +20 -0
- package/dist/src/useStateUpdater.d.ts.map +1 -0
- package/dist/src/useStateUpdater.js +43 -0
- package/dist/src/useStateUpdater.js.map +1 -0
- package/dist/src/useStateUpdater.test.d.ts +2 -0
- package/dist/src/useStateUpdater.test.d.ts.map +1 -0
- package/dist/src/useStateUpdater.test.js +69 -0
- package/dist/src/useStateUpdater.test.js.map +1 -0
- package/dist/src/useStateWithRef.d.ts +17 -0
- package/dist/src/useStateWithRef.d.ts.map +1 -0
- package/dist/src/useStateWithRef.js +31 -0
- package/dist/src/useStateWithRef.js.map +1 -0
- package/dist/src/useTimestamp.d.ts +12 -0
- package/dist/src/useTimestamp.d.ts.map +1 -0
- package/dist/src/useTimestamp.js +28 -0
- package/dist/src/useTimestamp.js.map +1 -0
- package/dist/stories/stale-callback.stories.d.ts +6 -0
- package/dist/stories/stale-callback.stories.d.ts.map +1 -0
- package/dist/stories/stale-callback.stories.js +59 -0
- package/dist/stories/stale-callback.stories.js.map +1 -0
- package/dist/stories/unmounted.stories.d.ts +6 -0
- package/dist/stories/unmounted.stories.d.ts.map +1 -0
- package/dist/stories/unmounted.stories.js +60 -0
- package/dist/stories/unmounted.stories.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +52 -0
- package/src/index.ts +11 -0
- package/src/useAsyncEffect.test.tsx +57 -0
- package/src/useAsyncEffect.ts +61 -0
- package/src/useControlledState.ts +39 -0
- package/src/useDynamicRef.ts +34 -0
- package/src/useMounted.ts +40 -0
- package/src/useStateUpdater.test.tsx +58 -0
- package/src/useStateUpdater.ts +40 -0
- package/src/useStateWithRef.ts +31 -0
- package/src/useTimestamp.ts +27 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2022 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import expect from 'expect';
|
|
6
|
+
import 'raf/polyfill';
|
|
7
|
+
import React, { useEffect } from 'react';
|
|
8
|
+
import ReactDOM from 'react-dom';
|
|
9
|
+
import { act } from 'react-dom/test-utils';
|
|
10
|
+
import waitForExpect from 'wait-for-expect';
|
|
11
|
+
|
|
12
|
+
import { useStateUpdater } from './useStateUpdater';
|
|
13
|
+
|
|
14
|
+
// Don't copy this.
|
|
15
|
+
const complex = {
|
|
16
|
+
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const Test = () => {
|
|
20
|
+
const [value,, updateValue] = useStateUpdater({ complex, items: [] });
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
updateValue({
|
|
23
|
+
items: {
|
|
24
|
+
$push: [1, 2, 3]
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}, []);
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<pre>{JSON.stringify(value)}</pre>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
let rootContainer: any;
|
|
35
|
+
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
rootContainer = document.createElement('div');
|
|
38
|
+
document.body.appendChild(rootContainer);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
afterEach(() => {
|
|
42
|
+
document.body.removeChild(rootContainer);
|
|
43
|
+
rootContainer = null;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe('useStateMutator', () => {
|
|
47
|
+
it('udpates the value.', async () => {
|
|
48
|
+
act(() => {
|
|
49
|
+
ReactDOM.render(<Test />, rootContainer);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const pre = rootContainer.querySelector('pre');
|
|
53
|
+
await waitForExpect(() => {
|
|
54
|
+
const data = JSON.parse(pre.textContent);
|
|
55
|
+
expect(data).toEqual({ complex, items: [1, 2, 3] });
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2022 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import update from 'immutability-helper';
|
|
6
|
+
import { Dispatch, SetStateAction, useState } from 'react';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Partially updates state without copying complex (expensive) objects.
|
|
10
|
+
* https://github.com/kolodny/immutability-helper
|
|
11
|
+
*
|
|
12
|
+
* ```tsx
|
|
13
|
+
* const [value,, updateValue] = useStateMutator({ items: [], ... });
|
|
14
|
+
* useEffect(() => {
|
|
15
|
+
* updateValue({
|
|
16
|
+
* items: {
|
|
17
|
+
* $push: [1, 2, 3] // Only update the items property.
|
|
18
|
+
* }
|
|
19
|
+
* })
|
|
20
|
+
* }, []);
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @param initialValue
|
|
24
|
+
*/
|
|
25
|
+
export const useStateUpdater = <T> (
|
|
26
|
+
initialValue: T
|
|
27
|
+
): [T, Dispatch<SetStateAction<T>>, (spec: any) => T] => {
|
|
28
|
+
const [value, setValue] = useState<T>(initialValue);
|
|
29
|
+
const handleUpdate = (spec: any) => {
|
|
30
|
+
const newValue = update(value, spec);
|
|
31
|
+
setValue(newValue);
|
|
32
|
+
return newValue;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return [
|
|
36
|
+
value,
|
|
37
|
+
setValue,
|
|
38
|
+
handleUpdate
|
|
39
|
+
];
|
|
40
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2022 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Dispatch, RefObject, SetStateAction, useEffect, useRef, useState } from 'react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Extension of useState to return an up-to-date reference.
|
|
9
|
+
* E.g., to use in callbacks where the state value is stale.
|
|
10
|
+
* https://css-tricks.com/dealing-with-stale-props-and-states-in-reacts-functional-components
|
|
11
|
+
*
|
|
12
|
+
* ```tsx
|
|
13
|
+
* const [value, setValue, valueRef] = useStateWithRef<string>();
|
|
14
|
+
* const handleAction = () => {
|
|
15
|
+
* console.log(valueRef.current);
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @param initialValue
|
|
20
|
+
*/
|
|
21
|
+
export const useStateWithRef = <V>(
|
|
22
|
+
initialValue?: V | (() => V)
|
|
23
|
+
): [V | undefined, Dispatch<SetStateAction<V | undefined>>, RefObject<V | undefined>] => {
|
|
24
|
+
const [value, setValue] = useState<V | undefined>(initialValue);
|
|
25
|
+
const ref = useRef<V>();
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
ref.current = value;
|
|
28
|
+
}, [initialValue, value]);
|
|
29
|
+
|
|
30
|
+
return [value, setValue, ref];
|
|
31
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2022 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Provides a timestamp that can be used to force re-rendering based on deps.
|
|
9
|
+
*
|
|
10
|
+
* ```tsx
|
|
11
|
+
* const [, update] = useTimestamp();
|
|
12
|
+
* const handleRefresh = () => update();
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* @param deps
|
|
16
|
+
*/
|
|
17
|
+
export const useTimestamp = (deps?: any[]): [number, () => void, number | undefined] => {
|
|
18
|
+
const [{ timestamp, previous }, setTimestamp] = useState<{ timestamp: number, previous?: number }>({
|
|
19
|
+
timestamp: Date.now()
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
setTimestamp({ timestamp: Date.now(), previous: timestamp });
|
|
24
|
+
}, deps || []);
|
|
25
|
+
|
|
26
|
+
return [timestamp, () => setTimestamp({ timestamp: Date.now(), previous: timestamp }), previous];
|
|
27
|
+
};
|