@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
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
## React Async
|
|
2
|
+
|
|
3
|
+
### Configuration
|
|
4
|
+
|
|
5
|
+
Add the following to `package.json`.
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
"toolchain": {
|
|
9
|
+
"forceCloseTests": true,
|
|
10
|
+
"jsdom": true,
|
|
11
|
+
"testingFramework": "mocha"
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The `react-dom/test-utils` requires the `raf` (React animation frame) polyfill to run headless.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import 'raf/polyfill';
|
|
19
|
+
import { act } from 'react-dom/test-utils';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Next
|
|
24
|
+
|
|
25
|
+
Evaluate the following:
|
|
26
|
+
|
|
27
|
+
- https://www.npmjs.com/package/react-async-hook (popular)
|
|
28
|
+
- https://www.npmjs.com/package/use-enhanced-state
|
|
29
|
+
- https://www.npmjs.com/package/react-hooks-lib
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './useAsyncEffect';
|
|
2
|
+
export * from './useControlledState';
|
|
3
|
+
export * from './useDynamicRef';
|
|
4
|
+
export * from './useMounted';
|
|
5
|
+
export * from './useStateUpdater';
|
|
6
|
+
export * from './useStateWithRef';
|
|
7
|
+
export * from './useTimestamp';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2022 DXOS.org
|
|
4
|
+
//
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
8
|
+
}) : (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
o[k2] = m[k];
|
|
11
|
+
}));
|
|
12
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
13
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
__exportStar(require("./useAsyncEffect"), exports);
|
|
17
|
+
__exportStar(require("./useControlledState"), exports);
|
|
18
|
+
__exportStar(require("./useDynamicRef"), exports);
|
|
19
|
+
__exportStar(require("./useMounted"), exports);
|
|
20
|
+
__exportStar(require("./useStateUpdater"), exports);
|
|
21
|
+
__exportStar(require("./useStateWithRef"), exports);
|
|
22
|
+
__exportStar(require("./useTimestamp"), exports);
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;;;;;;;;;;AAEF,mDAAiC;AACjC,uDAAqC;AACrC,kDAAgC;AAChC,+CAA6B;AAC7B,oDAAkC;AAClC,oDAAkC;AAClC,iDAA+B"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process async event with optional non-async destructor.
|
|
3
|
+
* Inspired by: https://github.com/rauldeheer/use-async-effect/blob/master/index.js
|
|
4
|
+
*
|
|
5
|
+
* ```tsx
|
|
6
|
+
* useAsyncEffect(async () => {
|
|
7
|
+
* await test();
|
|
8
|
+
* }, []);
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* The callback may check of the component is still mounted before doing state updates.
|
|
12
|
+
*
|
|
13
|
+
* ```tsx
|
|
14
|
+
* const [value, setValue] = useState<string>();
|
|
15
|
+
* useAsyncEffect<string>(async (isMounted) => {
|
|
16
|
+
* const value = await test();
|
|
17
|
+
* if (!isMounted()) {
|
|
18
|
+
* setValue(value);
|
|
19
|
+
* }
|
|
20
|
+
* }, () => console.log('Unmounted'), []);
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @param callback Receives a getter function that determines if the componet is still mounted.
|
|
24
|
+
* @param destructor Receives the value retuned from the callback.
|
|
25
|
+
* @param deps
|
|
26
|
+
*/
|
|
27
|
+
export declare const useAsyncEffect: <T>(callback: (isMounted: () => boolean) => Promise<T>, destructor?: any[] | ((value?: T | undefined) => void) | undefined, deps?: any[] | undefined) => void;
|
|
28
|
+
//# sourceMappingURL=useAsyncEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAsyncEffect.d.ts","sourceRoot":"","sources":["../../src/useAsyncEffect.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,eAAO,MAAM,cAAc,4BACH,MAAM,OAAO,kEACN,IAAI,gDAwBlC,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2022 DXOS.org
|
|
4
|
+
//
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useAsyncEffect = void 0;
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
/**
|
|
9
|
+
* Process async event with optional non-async destructor.
|
|
10
|
+
* Inspired by: https://github.com/rauldeheer/use-async-effect/blob/master/index.js
|
|
11
|
+
*
|
|
12
|
+
* ```tsx
|
|
13
|
+
* useAsyncEffect(async () => {
|
|
14
|
+
* await test();
|
|
15
|
+
* }, []);
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* The callback may check of the component is still mounted before doing state updates.
|
|
19
|
+
*
|
|
20
|
+
* ```tsx
|
|
21
|
+
* const [value, setValue] = useState<string>();
|
|
22
|
+
* useAsyncEffect<string>(async (isMounted) => {
|
|
23
|
+
* const value = await test();
|
|
24
|
+
* if (!isMounted()) {
|
|
25
|
+
* setValue(value);
|
|
26
|
+
* }
|
|
27
|
+
* }, () => console.log('Unmounted'), []);
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @param callback Receives a getter function that determines if the componet is still mounted.
|
|
31
|
+
* @param destructor Receives the value retuned from the callback.
|
|
32
|
+
* @param deps
|
|
33
|
+
*/
|
|
34
|
+
// TODO(burdon): Creade useAsyncMemo?
|
|
35
|
+
// TODO(burdon): Replace setImmediate everywhere (approx 30 places).
|
|
36
|
+
const useAsyncEffect = (callback, destructor, deps) => {
|
|
37
|
+
const [effectDestructor, effectDeps] = typeof destructor === 'function' ? [destructor, deps] : [undefined, destructor];
|
|
38
|
+
(0, react_1.useEffect)(() => {
|
|
39
|
+
let mounted = true;
|
|
40
|
+
let value;
|
|
41
|
+
const asyncResult = callback(() => mounted);
|
|
42
|
+
// TODO(burdon): Catch exception.
|
|
43
|
+
void Promise.resolve(asyncResult).then(result => {
|
|
44
|
+
value = result;
|
|
45
|
+
});
|
|
46
|
+
return () => {
|
|
47
|
+
mounted = false;
|
|
48
|
+
effectDestructor === null || effectDestructor === void 0 ? void 0 : effectDestructor(value);
|
|
49
|
+
};
|
|
50
|
+
}, effectDeps);
|
|
51
|
+
};
|
|
52
|
+
exports.useAsyncEffect = useAsyncEffect;
|
|
53
|
+
//# sourceMappingURL=useAsyncEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAsyncEffect.js","sourceRoot":"","sources":["../../src/useAsyncEffect.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;AAEF,iCAAkC;AAElC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qCAAqC;AACrC,oEAAoE;AAC7D,MAAM,cAAc,GAAG,CAC5B,QAAkD,EAClD,UAA0C,EAC1C,IAAY,EACZ,EAAE;IACF,MAAM,CACJ,gBAAgB,EAChB,UAAU,CACX,GAAG,OAAO,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAEpF,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,OAAO,GAAG,IAAI,CAAC;QAEnB,IAAI,KAAQ,CAAC;QACb,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC;QAE5C,iCAAiC;QACjC,KAAK,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;YAC9C,KAAK,GAAG,MAAM,CAAC;QACjB,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,OAAO,GAAG,KAAK,CAAC;YAChB,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,CAAG,KAAK,CAAC,CAAC;QAC5B,CAAC,CAAC;IACJ,CAAC,EAAE,UAAU,CAAC,CAAC;AACjB,CAAC,CAAC;AA1BW,QAAA,cAAc,kBA0BzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAsyncEffect.test.d.ts","sourceRoot":"","sources":["../../src/useAsyncEffect.test.tsx"],"names":[],"mappings":"AAKA,OAAO,cAAc,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2022 DXOS.org
|
|
4
|
+
//
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
8
|
+
}) : (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
o[k2] = m[k];
|
|
11
|
+
}));
|
|
12
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
13
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
14
|
+
}) : function(o, v) {
|
|
15
|
+
o["default"] = v;
|
|
16
|
+
});
|
|
17
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
18
|
+
if (mod && mod.__esModule) return mod;
|
|
19
|
+
var result = {};
|
|
20
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
21
|
+
__setModuleDefault(result, mod);
|
|
22
|
+
return result;
|
|
23
|
+
};
|
|
24
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
25
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
26
|
+
};
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
const expect_1 = __importDefault(require("expect"));
|
|
29
|
+
require("raf/polyfill");
|
|
30
|
+
const react_1 = __importStar(require("react"));
|
|
31
|
+
const react_dom_1 = __importDefault(require("react-dom"));
|
|
32
|
+
const test_utils_1 = require("react-dom/test-utils");
|
|
33
|
+
const wait_for_expect_1 = __importDefault(require("wait-for-expect"));
|
|
34
|
+
const useAsyncEffect_1 = require("./useAsyncEffect");
|
|
35
|
+
const doAsync = async (value) => {
|
|
36
|
+
return await new Promise((resolve) => {
|
|
37
|
+
resolve(value);
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
const Test = () => {
|
|
41
|
+
const [value, setValue] = (0, react_1.useState)();
|
|
42
|
+
(0, useAsyncEffect_1.useAsyncEffect)(async (isMounted) => {
|
|
43
|
+
const value = await doAsync('DXOS');
|
|
44
|
+
if (isMounted()) {
|
|
45
|
+
setValue(value);
|
|
46
|
+
}
|
|
47
|
+
}, []);
|
|
48
|
+
return (react_1.default.createElement("h1", null, value));
|
|
49
|
+
};
|
|
50
|
+
let rootContainer;
|
|
51
|
+
beforeEach(() => {
|
|
52
|
+
rootContainer = document.createElement('div');
|
|
53
|
+
document.body.appendChild(rootContainer);
|
|
54
|
+
});
|
|
55
|
+
afterEach(() => {
|
|
56
|
+
document.body.removeChild(rootContainer);
|
|
57
|
+
rootContainer = null;
|
|
58
|
+
});
|
|
59
|
+
describe('useAsyncEffect', () => {
|
|
60
|
+
it('gets async value.', async () => {
|
|
61
|
+
(0, test_utils_1.act)(() => {
|
|
62
|
+
react_dom_1.default.render(react_1.default.createElement(Test, null), rootContainer);
|
|
63
|
+
});
|
|
64
|
+
const h1 = rootContainer.querySelector('h1');
|
|
65
|
+
await (0, wait_for_expect_1.default)(() => {
|
|
66
|
+
(0, expect_1.default)(h1.textContent).toEqual('DXOS');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=useAsyncEffect.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAsyncEffect.test.js","sourceRoot":"","sources":["../../src/useAsyncEffect.test.tsx"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;;;;;;;;;;;;;;;;;;;;;;AAEF,oDAA4B;AAC5B,wBAAsB;AACtB,+CAAwC;AACxC,0DAAiC;AACjC,qDAA2C;AAC3C,sEAA4C;AAE5C,qDAAkD;AAElD,MAAM,OAAO,GAAG,KAAK,EAAQ,KAAQ,EAAE,EAAE;IACvC,OAAO,MAAM,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,EAAE;QACtC,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,GAAG,EAAE;IAChB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,GAAU,CAAC;IAC7C,IAAA,+BAAc,EAAC,KAAK,EAAE,SAAS,EAAE,EAAE;QACjC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,SAAS,EAAE,EAAE;YACf,QAAQ,CAAC,KAAK,CAAC,CAAC;SACjB;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,0CAAK,KAAK,CAAM,CACjB,CAAC;AACJ,CAAC,CAAC;AAEF,IAAI,aAAkB,CAAC;AAEvB,UAAU,CAAC,GAAG,EAAE;IACd,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9C,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;IACzC,aAAa,GAAG,IAAI,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;QACjC,IAAA,gBAAG,EAAC,GAAG,EAAE;YACP,mBAAQ,CAAC,MAAM,CAAC,8BAAC,IAAI,OAAG,EAAE,aAAa,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,IAAA,yBAAa,EAAC,GAAG,EAAE;YACvB,IAAA,gBAAM,EAAC,EAAE,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Dispatch, SetStateAction } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Hook that manages state and that can be updated by caller.
|
|
4
|
+
* The optional callback is triggered only if the state is updated internally.
|
|
5
|
+
*
|
|
6
|
+
* ```tsx
|
|
7
|
+
* const Component = ({ value: controlledValue, onChange }: { value: string, onChange: (value:string) => void }) => {
|
|
8
|
+
* const [value, setValue] = useControlledState(controlledValue, onChange);
|
|
9
|
+
* const handleUpdate = (value: string) => setValue(value);
|
|
10
|
+
* }
|
|
11
|
+
*
|
|
12
|
+
* @param controlledValue
|
|
13
|
+
* @param onChange
|
|
14
|
+
* @param deps other deps that may change the state
|
|
15
|
+
*/
|
|
16
|
+
export declare const useControlledState: <T>(controlledValue: T, onChange?: ((value: T) => void) | undefined, deps?: any[] | undefined) => [T, Dispatch<SetStateAction<T>>];
|
|
17
|
+
//# sourceMappingURL=useControlledState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useControlledState.d.ts","sourceRoot":"","sources":["../../src/useControlledState.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAuB,MAAM,OAAO,CAAC;AAEtE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,oDAEJ,IAAI,4EAgB9B,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2022 DXOS.org
|
|
4
|
+
//
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useControlledState = void 0;
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
/**
|
|
9
|
+
* Hook that manages state and that can be updated by caller.
|
|
10
|
+
* The optional callback is triggered only if the state is updated internally.
|
|
11
|
+
*
|
|
12
|
+
* ```tsx
|
|
13
|
+
* const Component = ({ value: controlledValue, onChange }: { value: string, onChange: (value:string) => void }) => {
|
|
14
|
+
* const [value, setValue] = useControlledState(controlledValue, onChange);
|
|
15
|
+
* const handleUpdate = (value: string) => setValue(value);
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* @param controlledValue
|
|
19
|
+
* @param onChange
|
|
20
|
+
* @param deps other deps that may change the state
|
|
21
|
+
*/
|
|
22
|
+
const useControlledState = (controlledValue, onChange, deps) => {
|
|
23
|
+
const [value, setValue] = (0, react_1.useState)(controlledValue);
|
|
24
|
+
(0, react_1.useEffect)(() => {
|
|
25
|
+
setValue(controlledValue);
|
|
26
|
+
}, [controlledValue, ...(deps !== null && deps !== void 0 ? deps : [])]);
|
|
27
|
+
return [
|
|
28
|
+
value,
|
|
29
|
+
(callback) => {
|
|
30
|
+
const newValue = (typeof callback === 'function') ? callback(value) : callback;
|
|
31
|
+
setValue(newValue);
|
|
32
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
|
|
33
|
+
}
|
|
34
|
+
];
|
|
35
|
+
};
|
|
36
|
+
exports.useControlledState = useControlledState;
|
|
37
|
+
//# sourceMappingURL=useControlledState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useControlledState.js","sourceRoot":"","sources":["../../src/useControlledState.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;AAEF,iCAAsE;AAEtE;;;;;;;;;;;;;GAaG;AACI,MAAM,kBAAkB,GAAG,CAChC,eAAkB,EAClB,QAA6B,EAC7B,IAAY,EACsB,EAAE;IACpC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAI,eAAe,CAAC,CAAC;IACvD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,QAAQ,CAAC,eAAe,CAAC,CAAC;IAC5B,CAAC,EAAE,CAAC,eAAe,EAAE,GAAG,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAEvC,OAAO;QACL,KAAK;QACL,CAAC,QAAkC,EAAE,EAAE;YACrC,MAAM,QAAQ,GAAG,CAAC,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,CAAE,QAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;YAC7F,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnB,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,QAAQ,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAlBW,QAAA,kBAAkB,sBAkB7B"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Extension of useRef that contains computed values based on dependencies.
|
|
4
|
+
* E.g., to use in callbacks where the state value is stale.
|
|
5
|
+
*
|
|
6
|
+
* ```tsx
|
|
7
|
+
* const valueRef = useDynamicRef<() => value>([value]);
|
|
8
|
+
* const handleAction = () => {
|
|
9
|
+
* console.log(valueRef.current);
|
|
10
|
+
* }
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* @param initialValue
|
|
14
|
+
* @param deps
|
|
15
|
+
*/
|
|
16
|
+
export declare const useDynamicRef: <V>(initialValue: () => V, deps: any[]) => RefObject<V>;
|
|
17
|
+
//# sourceMappingURL=useDynamicRef.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDynamicRef.d.ts","sourceRoot":"","sources":["../../src/useDynamicRef.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAA+B,MAAM,OAAO,CAAC;AAE/D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa,mCAElB,GAAG,EAAE,iBAWZ,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2022 DXOS.org
|
|
4
|
+
//
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useDynamicRef = void 0;
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
/**
|
|
9
|
+
* Extension of useRef that contains computed values based on dependencies.
|
|
10
|
+
* E.g., to use in callbacks where the state value is stale.
|
|
11
|
+
*
|
|
12
|
+
* ```tsx
|
|
13
|
+
* const valueRef = useDynamicRef<() => value>([value]);
|
|
14
|
+
* const handleAction = () => {
|
|
15
|
+
* console.log(valueRef.current);
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @param initialValue
|
|
20
|
+
* @param deps
|
|
21
|
+
*/
|
|
22
|
+
const useDynamicRef = (initialValue, deps) => {
|
|
23
|
+
const [, setValue] = (0, react_1.useState)(initialValue);
|
|
24
|
+
const ref = (0, react_1.useRef)(initialValue());
|
|
25
|
+
(0, react_1.useEffect)(() => {
|
|
26
|
+
ref.current = initialValue();
|
|
27
|
+
// Must update state to trigger render cycle.
|
|
28
|
+
setValue(ref.current);
|
|
29
|
+
}, deps);
|
|
30
|
+
return ref;
|
|
31
|
+
};
|
|
32
|
+
exports.useDynamicRef = useDynamicRef;
|
|
33
|
+
//# sourceMappingURL=useDynamicRef.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDynamicRef.js","sourceRoot":"","sources":["../../src/useDynamicRef.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;AAEF,iCAA+D;AAE/D;;;;;;;;;;;;;GAaG;AACI,MAAM,aAAa,GAAG,CAC3B,YAAqB,EACrB,IAAW,EACG,EAAE;IAChB,MAAM,CAAC,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAI,YAAY,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,IAAA,cAAM,EAAI,YAAY,EAAE,CAAC,CAAC;IACtC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,GAAG,CAAC,OAAO,GAAG,YAAY,EAAE,CAAC;QAC7B,6CAA6C;QAC7C,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC,EAAE,IAAI,CAAC,CAAC;IAET,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAbW,QAAA,aAAa,iBAaxB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides a function to test if the component is still mounted.
|
|
3
|
+
* Avoids the following error:
|
|
4
|
+
* "Warning: Can't perform a React state update on an unmounted component."
|
|
5
|
+
*
|
|
6
|
+
* ```tsx
|
|
7
|
+
* const Test = () => {
|
|
8
|
+
* const isMounted = useMounted();
|
|
9
|
+
* const [value, setValue] = useState('');
|
|
10
|
+
* useEffect(() => {
|
|
11
|
+
* setTimeout(() => {
|
|
12
|
+
* if (isMounted()) {
|
|
13
|
+
* setValue(value);
|
|
14
|
+
* }
|
|
15
|
+
* }, 1000);
|
|
16
|
+
* }, []);
|
|
17
|
+
*
|
|
18
|
+
* return (
|
|
19
|
+
* <div>{value}</div>
|
|
20
|
+
* );
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare const useMounted: () => () => boolean;
|
|
25
|
+
//# sourceMappingURL=useMounted.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMounted.d.ts","sourceRoot":"","sources":["../../src/useMounted.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,UAAU,qBAUtB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2022 DXOS.org
|
|
4
|
+
//
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useMounted = void 0;
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
/**
|
|
9
|
+
* Provides a function to test if the component is still mounted.
|
|
10
|
+
* Avoids the following error:
|
|
11
|
+
* "Warning: Can't perform a React state update on an unmounted component."
|
|
12
|
+
*
|
|
13
|
+
* ```tsx
|
|
14
|
+
* const Test = () => {
|
|
15
|
+
* const isMounted = useMounted();
|
|
16
|
+
* const [value, setValue] = useState('');
|
|
17
|
+
* useEffect(() => {
|
|
18
|
+
* setTimeout(() => {
|
|
19
|
+
* if (isMounted()) {
|
|
20
|
+
* setValue(value);
|
|
21
|
+
* }
|
|
22
|
+
* }, 1000);
|
|
23
|
+
* }, []);
|
|
24
|
+
*
|
|
25
|
+
* return (
|
|
26
|
+
* <div>{value}</div>
|
|
27
|
+
* );
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
const useMounted = () => {
|
|
32
|
+
const mounted = (0, react_1.useRef)(false);
|
|
33
|
+
(0, react_1.useEffect)(() => {
|
|
34
|
+
mounted.current = true;
|
|
35
|
+
return () => {
|
|
36
|
+
mounted.current = false;
|
|
37
|
+
};
|
|
38
|
+
}, []);
|
|
39
|
+
return () => mounted.current;
|
|
40
|
+
};
|
|
41
|
+
exports.useMounted = useMounted;
|
|
42
|
+
//# sourceMappingURL=useMounted.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMounted.js","sourceRoot":"","sources":["../../src/useMounted.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;AAEF,iCAA0C;AAE1C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACI,MAAM,UAAU,GAAG,GAAG,EAAE;IAC7B,MAAM,OAAO,GAAG,IAAA,cAAM,EAAC,KAAK,CAAC,CAAC;IAC9B,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;QACvB,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC;QAC1B,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;AAC/B,CAAC,CAAC;AAVW,QAAA,UAAU,cAUrB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Dispatch, SetStateAction } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Partially updates state without copying complex (expensive) objects.
|
|
4
|
+
* https://github.com/kolodny/immutability-helper
|
|
5
|
+
*
|
|
6
|
+
* ```tsx
|
|
7
|
+
* const [value,, updateValue] = useStateMutator({ items: [], ... });
|
|
8
|
+
* useEffect(() => {
|
|
9
|
+
* updateValue({
|
|
10
|
+
* items: {
|
|
11
|
+
* $push: [1, 2, 3] // Only update the items property.
|
|
12
|
+
* }
|
|
13
|
+
* })
|
|
14
|
+
* }, []);
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @param initialValue
|
|
18
|
+
*/
|
|
19
|
+
export declare const useStateUpdater: <T>(initialValue: T) => [T, Dispatch<SetStateAction<T>>, (spec: any) => T];
|
|
20
|
+
//# sourceMappingURL=useStateUpdater.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStateUpdater.d.ts","sourceRoot":"","sources":["../../src/useStateUpdater.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAY,MAAM,OAAO,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,eAAe,kEAEe,GAAG,OAa7C,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2022 DXOS.org
|
|
4
|
+
//
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.useStateUpdater = void 0;
|
|
10
|
+
const immutability_helper_1 = __importDefault(require("immutability-helper"));
|
|
11
|
+
const react_1 = require("react");
|
|
12
|
+
/**
|
|
13
|
+
* Partially updates state without copying complex (expensive) objects.
|
|
14
|
+
* https://github.com/kolodny/immutability-helper
|
|
15
|
+
*
|
|
16
|
+
* ```tsx
|
|
17
|
+
* const [value,, updateValue] = useStateMutator({ items: [], ... });
|
|
18
|
+
* useEffect(() => {
|
|
19
|
+
* updateValue({
|
|
20
|
+
* items: {
|
|
21
|
+
* $push: [1, 2, 3] // Only update the items property.
|
|
22
|
+
* }
|
|
23
|
+
* })
|
|
24
|
+
* }, []);
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @param initialValue
|
|
28
|
+
*/
|
|
29
|
+
const useStateUpdater = (initialValue) => {
|
|
30
|
+
const [value, setValue] = (0, react_1.useState)(initialValue);
|
|
31
|
+
const handleUpdate = (spec) => {
|
|
32
|
+
const newValue = (0, immutability_helper_1.default)(value, spec);
|
|
33
|
+
setValue(newValue);
|
|
34
|
+
return newValue;
|
|
35
|
+
};
|
|
36
|
+
return [
|
|
37
|
+
value,
|
|
38
|
+
setValue,
|
|
39
|
+
handleUpdate
|
|
40
|
+
];
|
|
41
|
+
};
|
|
42
|
+
exports.useStateUpdater = useStateUpdater;
|
|
43
|
+
//# sourceMappingURL=useStateUpdater.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStateUpdater.js","sourceRoot":"","sources":["../../src/useStateUpdater.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;;;;AAEF,8EAAyC;AACzC,iCAA2D;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACI,MAAM,eAAe,GAAG,CAC7B,YAAe,EACqC,EAAE;IACtD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAI,YAAY,CAAC,CAAC;IACpD,MAAM,YAAY,GAAG,CAAC,IAAS,EAAE,EAAE;QACjC,MAAM,QAAQ,GAAG,IAAA,6BAAM,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACrC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnB,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO;QACL,KAAK;QACL,QAAQ;QACR,YAAY;KACb,CAAC;AACJ,CAAC,CAAC;AAfW,QAAA,eAAe,mBAe1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStateUpdater.test.d.ts","sourceRoot":"","sources":["../../src/useStateUpdater.test.tsx"],"names":[],"mappings":"AAKA,OAAO,cAAc,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2022 DXOS.org
|
|
4
|
+
//
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
8
|
+
}) : (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
o[k2] = m[k];
|
|
11
|
+
}));
|
|
12
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
13
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
14
|
+
}) : function(o, v) {
|
|
15
|
+
o["default"] = v;
|
|
16
|
+
});
|
|
17
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
18
|
+
if (mod && mod.__esModule) return mod;
|
|
19
|
+
var result = {};
|
|
20
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
21
|
+
__setModuleDefault(result, mod);
|
|
22
|
+
return result;
|
|
23
|
+
};
|
|
24
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
25
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
26
|
+
};
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
const expect_1 = __importDefault(require("expect"));
|
|
29
|
+
require("raf/polyfill");
|
|
30
|
+
const react_1 = __importStar(require("react"));
|
|
31
|
+
const react_dom_1 = __importDefault(require("react-dom"));
|
|
32
|
+
const test_utils_1 = require("react-dom/test-utils");
|
|
33
|
+
const wait_for_expect_1 = __importDefault(require("wait-for-expect"));
|
|
34
|
+
const useStateUpdater_1 = require("./useStateUpdater");
|
|
35
|
+
// Don't copy this.
|
|
36
|
+
const complex = {};
|
|
37
|
+
const Test = () => {
|
|
38
|
+
const [value, , updateValue] = (0, useStateUpdater_1.useStateUpdater)({ complex, items: [] });
|
|
39
|
+
(0, react_1.useEffect)(() => {
|
|
40
|
+
updateValue({
|
|
41
|
+
items: {
|
|
42
|
+
$push: [1, 2, 3]
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}, []);
|
|
46
|
+
return (react_1.default.createElement("pre", null, JSON.stringify(value)));
|
|
47
|
+
};
|
|
48
|
+
let rootContainer;
|
|
49
|
+
beforeEach(() => {
|
|
50
|
+
rootContainer = document.createElement('div');
|
|
51
|
+
document.body.appendChild(rootContainer);
|
|
52
|
+
});
|
|
53
|
+
afterEach(() => {
|
|
54
|
+
document.body.removeChild(rootContainer);
|
|
55
|
+
rootContainer = null;
|
|
56
|
+
});
|
|
57
|
+
describe('useStateMutator', () => {
|
|
58
|
+
it('udpates the value.', async () => {
|
|
59
|
+
(0, test_utils_1.act)(() => {
|
|
60
|
+
react_dom_1.default.render(react_1.default.createElement(Test, null), rootContainer);
|
|
61
|
+
});
|
|
62
|
+
const pre = rootContainer.querySelector('pre');
|
|
63
|
+
await (0, wait_for_expect_1.default)(() => {
|
|
64
|
+
const data = JSON.parse(pre.textContent);
|
|
65
|
+
(0, expect_1.default)(data).toEqual({ complex, items: [1, 2, 3] });
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
//# sourceMappingURL=useStateUpdater.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStateUpdater.test.js","sourceRoot":"","sources":["../../src/useStateUpdater.test.tsx"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;;;;;;;;;;;;;;;;;;;;;;AAEF,oDAA4B;AAC5B,wBAAsB;AACtB,+CAAyC;AACzC,0DAAiC;AACjC,qDAA2C;AAC3C,sEAA4C;AAE5C,uDAAoD;AAEpD,mBAAmB;AACnB,MAAM,OAAO,GAAG,EAEf,CAAC;AAEF,MAAM,IAAI,GAAG,GAAG,EAAE;IAChB,MAAM,CAAC,KAAK,EAAC,EAAE,WAAW,CAAC,GAAG,IAAA,iCAAe,EAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IACtE,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,WAAW,CAAC;YACV,KAAK,EAAE;gBACL,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;aACjB;SACF,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,2CAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAO,CACnC,CAAC;AACJ,CAAC,CAAC;AAEF,IAAI,aAAkB,CAAC;AAEvB,UAAU,CAAC,GAAG,EAAE;IACd,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9C,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;IACzC,aAAa,GAAG,IAAI,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;QAClC,IAAA,gBAAG,EAAC,GAAG,EAAE;YACP,mBAAQ,CAAC,MAAM,CAAC,8BAAC,IAAI,OAAG,EAAE,aAAa,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,aAAa,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,IAAA,yBAAa,EAAC,GAAG,EAAE;YACvB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACzC,IAAA,gBAAM,EAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Dispatch, RefObject, SetStateAction } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Extension of useState to return an up-to-date reference.
|
|
4
|
+
* E.g., to use in callbacks where the state value is stale.
|
|
5
|
+
* https://css-tricks.com/dealing-with-stale-props-and-states-in-reacts-functional-components
|
|
6
|
+
*
|
|
7
|
+
* ```tsx
|
|
8
|
+
* const [value, setValue, valueRef] = useStateWithRef<string>();
|
|
9
|
+
* const handleAction = () => {
|
|
10
|
+
* console.log(valueRef.current);
|
|
11
|
+
* }
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @param initialValue
|
|
15
|
+
*/
|
|
16
|
+
export declare const useStateWithRef: <V>(initialValue?: V | (() => V) | undefined) => [V | undefined, Dispatch<SetStateAction<V | undefined>>, RefObject<V | undefined>];
|
|
17
|
+
//# sourceMappingURL=useStateWithRef.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStateWithRef.d.ts","sourceRoot":"","sources":["../../src/useStateWithRef.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAA+B,MAAM,OAAO,CAAC;AAEzF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,qIAU3B,CAAC"}
|