Skip to content

Commit a0a7144

Browse files
committedJan 4, 2021
Improved README.md;
Refactored playground; Added LICENSE.txt;
1 parent 5529feb commit a0a7144

File tree

6 files changed

+141
-14
lines changed

6 files changed

+141
-14
lines changed
 

‎.gitignore

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
/coverage/
22
/.nyc_output/
33
/dist/
4+
/test/build/
5+
/playground/build/
46
/node_modules/
57
/trash/
68
/.idea/
7-
/test/tests/decorators.js
8-
/test/tests/decorators.legacy.js
9-
/playground/dist/

‎LICENSE.txt

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
The MIT License (MIT)
3+
4+
Copyright (c) 2021 Mozgovoy Dmitriy <http://www.github.com/DigitalBrainJS> and Contributors
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the 'Software'), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is furnished
11+
to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20+
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

‎README.md

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
![Travis (.com)](https://img.shields.io/travis/com/DigitalBrainJS/use-async-effect)
2+
![npm](https://img.shields.io/npm/dm/use-async-effect2)
3+
![npm bundle size](https://img.shields.io/bundlephobia/minzip/use-async-effect)
4+
![David](https://img.shields.io/david/DigitalBrainJS/use-async-effect)
5+
[![Stars](https://badgen.net/github/stars/DigitalBrainJS/use-async-effect)](https://github.com/DigitalBrainJS/use-async-effect/stargazers)
6+
7+
## useAsyncEffect2
8+
The library provides a React hook with ability to automatically cancel asynchronous code inside it.
9+
It just makes it easier to write cancelable asynchronous code that doesn't cause
10+
the following React issue when unmounting, if your asynchronous tasks that change state are pending:
11+
````
12+
Warning: Can't perform a React state update on an unmounted component.
13+
This is an no-op, but it indicates a memory leak in your application.
14+
To fix, cancel all subscriptions and asynchronous task in "a useEffect cleanup function".
15+
````
16+
It uses [c-promise2](https://www.npmjs.com/package/c-promise2) to make it work.
17+
When it used in conjunction with other libraries that work with the CPromise,
18+
such as [cp-fetch](https://www.npmjs.com/package/cp-fetch) and [cp-axios](https://www.npmjs.com/package/cp-axios),
19+
you get a powerful tool for building asynchronous logic for your components.
20+
You just have to use `generators` instead of an async function to make your code cancellable,
21+
but basically, that just means you will have to use `yield` instead of `await` keyword.
22+
## Usage example
23+
Minimal example with json request [Live demo](https://codesandbox.io/s/friendly-murdock-wxq8u?file=/src/App.js)
24+
````jsx
25+
import React from "react";
26+
import {useState} from "react";
27+
import {useAsyncEffect} from "use-async-effect2";
28+
import cpFetch from "cp-fetch";
29+
30+
function JSONViewer(props) {
31+
const [text, setText] = useState("");
32+
33+
useAsyncEffect(function* () {
34+
setText("fetching...");
35+
const response = yield cpFetch(props.url);
36+
const json = yield response.json();
37+
setText(`Success: ${JSON.stringify(json)}`);
38+
}, [props.url]);
39+
40+
return <div>{text}</div>;
41+
}
42+
````
43+
Example with timeout & error handling ([Live demo](https://codesandbox.io/s/async-effect-demo1-vho29)):
44+
````jsx
45+
import React from "react";
46+
import {useState} from "react";
47+
import {useAsyncEffect, E_REASON_UNMOUNTED} from "use-async-effect2";
48+
import {CanceledError} from "c-promise2";
49+
import cpFetch from "cp-fetch";
50+
51+
export default function TestComponent(props) {
52+
const [text, setText] = useState("");
53+
54+
const [cancel]= useAsyncEffect(function* ({onCancel}) {
55+
console.log("mount");
56+
57+
this.timeout(5000);
58+
59+
onCancel(()=> console.log('scope canceled'));
60+
61+
try {
62+
setText("fetching...");
63+
const response = yield cpFetch(props.url);
64+
const json = yield response.json();
65+
setText(`Success: ${JSON.stringify(json)}`);
66+
} catch (err) {
67+
CanceledError.rethrow(err, E_REASON_UNMOUNTED); //passthrough
68+
setText(`Failed: ${err}`);
69+
}
70+
71+
return () => {
72+
console.log("unmount", this.isCanceled);
73+
};
74+
}, [props.url]);
75+
76+
//setTimeout(()=> cancel("Ooops!"), 1000);
77+
78+
return <div>{text}</div>;
79+
}
80+
````
81+
To learn more about available features, see the c-promise2 [documentation](https://www.npmjs.com/package/c-promise2).
82+
83+
## Playground
84+
85+
To get it, clone the repository and run `npm run playground` in the project directory or
86+
just use the codesandbox [demo](https://codesandbox.io/s/async-effect-demo1-vho29) to play with the library online.
87+
88+
## Related projects
89+
- [c-promise2](https://www.npmjs.com/package/c-promise2) - promise with cancellation, decorators, timeouts, progress capturing, pause and user signals support
90+
- [cp-axios](https://www.npmjs.com/package/cp-axios) - a simple axios wrapper that provides an advanced cancellation api
91+
- [cp-fetch](https://www.npmjs.com/package/cp-fetch) - fetch with timeouts and request cancellation
92+
93+
## License
94+
95+
The MIT License Copyright (c) 2021 Dmitriy Mozgovoy robotshara@gmail.com
96+
97+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
98+
99+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
100+
101+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
102+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
103+
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
104+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
105+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

‎package.json

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"name": "use-async-effect",
33
"version": "0.0.0",
4-
"description": "cancellable async effect hook",
5-
"main": "lib/index.js",
4+
"description": "Async effect hook with cancellation and other powers of CPromise",
5+
"main": "lib/use-async-effect.js",
66
"scripts": {
77
"test": "npm run test:build && mocha-headless-chrome -f test/test.html",
88
"test:build": "rollup ./test/src/index.js --file ./test/build/index.js --format iife --config ./test/rollup.config.js",
99
"playground": "npm run playground:build && concurrently --kill-others \"npm run playground:server\" \"npm run playground:watch\"",
1010
"playground:run": "node playground/build/index.js || true",
1111
"playground:build": "rollup ./playground/src/index.js --file ./playground/build/index.js --format iife --config ./playground/rollup.config.js",
12-
"playground:watch": "nodemon --delay 1500ms --watch ./playground/src/ --watch lib/ --exec \\\"npm run playground:build\\\"",
12+
"playground:watch": "nodemon --delay 1000ms --watch ./playground/src/ --watch lib/ --exec \\\"npm run playground:build\\\"",
1313
"playground:server": "browser-sync start --server --index ./playground/index.html --files \"./playground/build/*.*\""
1414
},
1515
"author": {
@@ -19,7 +19,13 @@
1919
},
2020
"license": "MIT",
2121
"keywords": [
22+
"React",
23+
"hook",
24+
"useEffect",
25+
"setState",
2226
"promise",
27+
"c-promise",
28+
"cpromise",
2329
"cancelable",
2430
"cancellable",
2531
"p-cancelable",
@@ -47,7 +53,6 @@
4753
"bluebird",
4854
"deferred",
4955
"react",
50-
"setState",
5156
"cancellation",
5257
"aborting",
5358
"close",

‎playground/src/App.js

-2
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@ export default class App extends React.Component {
1111
}
1212

1313
onFetchClick(){
14-
console.log(`fetch click`);
1514
this.setState(({_url})=> this.setState({url: _url}))
1615
}
1716

1817
onClick() {
19-
console.log(`click`);
2018
this.setState({ timestamp: Date.now() });
2119
}
2220

‎playground/src/TestComponent.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import React from "react";
2-
import {useEffect, useState} from "react";
3-
import ReactDOM from "react-dom";
2+
import {useState} from "react";
43
import {useAsyncEffect, E_REASON_UNMOUNTED} from "../../lib/use-async-effect";
5-
import {CanceledError, CPromise} from "c-promise2";
4+
import {CanceledError} from "c-promise2";
65
import cpFetch from "cp-fetch";
76

87
export default function TestComponent(props) {
98
const [text, setText] = useState("");
109

11-
const [cancel, ref]= useAsyncEffect(function* ({onCancel}) {
10+
const [cancel]= useAsyncEffect(function* ({onCancel}) {
1211
console.log("mount");
1312

14-
//this.timeout(1000);
13+
this.timeout(5000);
1514

1615
onCancel(()=> console.log('scope canceled'));
1716

0 commit comments

Comments
 (0)
Please sign in to comment.