You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
***readme:** various edits ([#90](https://github.com/shtaif/react-async-iterators/issues/90)) ([27a8d41](https://github.com/shtaif/react-async-iterators/commit/27a8d41f3cb3f7591c9b0566d63a9f0aa3a388ee))
7
+
***readme:** various edits for `README.md` ([#91](https://github.com/shtaif/react-async-iterators/issues/91)) ([0f91ca4](https://github.com/shtaif/react-async-iterators/commit/0f91ca4fc9e929cafbfb70b0f4b01e5b455a77b5))
Copy file name to clipboardExpand all lines: README.md
+96-7Lines changed: 96 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -13,11 +13,17 @@
13
13
14
14
</p>
15
15
16
-
A React.js library that makes it __easy and satisfying__ to integrate and render JS async iterators across and throughout your app's components. Expanding from that, it allows you to describe and propagate various aspects and states of your app in actual async iterator form, letting it tap into the full benefits and flexibility in this JS construct.
16
+
A React.js library that makes it __easy and satisfying__ to integrate and render JS async iterators across and throughout your app's components. Expanding from that, it enables you to describe and propagate states and various aspects of your app in actual async iterator form, tapping into the full benefits and flexibility of this JS construct.
17
17
18
+
To facilitate this, `react-async-iterators` offers a set of tools specifically tailored for the frontend and React while embracing composability with the upcoming standardization of [Async Iterator Helpers proposal](https://github.com/tc39/proposal-async-iterator-helpers) as well as utility libraries such as [iter-tools](https://github.com/iter-tools/iter-tools), [IxJS](https://github.com/ReactiveX/IxJS) and more. You may use this library as a one-off in your code; e.g got an async iterable from a third-party SDK and just need to consume it. You may also employ it throughout your entire app. That's up to you. The library just aims to be _"everything async iterators and React"_ and is fully tree-shakable.
18
19
20
+
The goal behind this library is to promote a mental model where every piece of data in a JavaScript program can be expressed either in a plain and static form, or in a ___dynamic, self-evolving___ form - an async iterable. That by simply wrapping a value in an async iterator or iterable, it becomes a self-updating entity while remaining first-class data. From this, it follows naturally that interfaces should and could intuitively accommodate either kind as received input, and seamlessly adapt to any changes over time just as you'd expect.
19
21
20
-
### Illustration:
22
+
The library will continue to expand with new tools over time.
23
+
24
+
25
+
26
+
### Illustration
21
27
22
28
[](https://stackblitz.com/edit/react-async-iterators-example-3?file=src%2FApp.tsx)
23
29
@@ -27,7 +33,7 @@ import { It } from 'react-async-iterators';
27
33
const randoms = {
28
34
async*[Symbol.asyncIterator]() {
29
35
while (true) {
30
-
awaitnewPromise((r)=>setTimeout(r, 500));
36
+
awaitnewPromise(r=>setTimeout(r, 500));
31
37
const x =Math.random();
32
38
yieldMath.round(x*10);
33
39
}
@@ -58,12 +64,24 @@ const randoms = {
58
64
// etc.
59
65
```
60
66
61
-
Below is another interactive demo showing how to consume the `EventSource` web API (A.K.A [SSE](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)) converted into async iterable using the [`iterified`](https://github.com/shtaif/iterified) package:
62
67
63
-
[](https://stackblitz.com/edit/react-async-iterators-example-5?file=src%2FApp.tsx)
64
68
69
+
### More examples
70
+
71
+
- Interactive demo showing how to consume the `EventSource` web API ([Server-Sent-Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)) converted into async iterable using the [`iterified`](https://github.com/shtaif/iterified) package:
72
+
<br/><br/>[](https://stackblitz.com/edit/react-async-iterators-example-5?file=src%2FApp.tsx)
73
+
74
+
- Interactive demo showing how to consume a [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) converted into async iterable using the [`iterified`](https://github.com/shtaif/iterified) package:
75
+
<br/><br/>[](https://stackblitz.com/edit/react-async-iterators-example-6?file=src%2FApp.tsx)
65
76
66
77
78
+
79
+
## 🔥 🔥 🔥
80
+
81
+
If you find this package helpful, please consider giving it a star! ⭐️<br/>
82
+
Something isn't right? don't hesitate to open an issue! 👍<br/>
@@ -173,7 +192,7 @@ Slightly obvious to say, the React ecosystem is featuring many methods and tools
173
192
174
193
- When apps involve any _asynchronously-generated series_ of data, such as data updated via recurring timers, WebSocket messages, GraphQL subscriptions, Geolocation watching and more...
175
194
176
-
- When rendering a complex form or dynamic widget with large nested component tree for which UI updates might impact UI performance.
195
+
- When rendering a complex form or dynamic widget with large nested component tree for which updates might impact UI performance.
177
196
178
197
179
198
@@ -223,7 +242,7 @@ import { It, type IterationResult } from 'react-async-iterators';
223
242
224
243
Async iterables can be hooked into your components and consumed using [`<It>`](#it) and [`<ItMulti>`](#itmulti), or their hook counterparts [`useAsyncIter`](#useasynciter) and [`useAsyncIterMulti`](#useasyncitermulti) respectively.
225
244
226
-
The iteration values and states are expressed via a consistent structure (see exaustive list in [this breakdown](#iteration-state-object-detailed-breakdown)).<br/>
245
+
The iteration values and states are expressed via a consistent structure (see exaustive list in [this breakdown](#iteration-state-properties-breakdown)).<br/>
Given some async iterables, a side-effect function and a computed list of dependencies - runs the provided side-effect whenever any of the provided dependencies change from the previously seen ones, letting you derive them from the values yielded by the async iterables.
1217
+
1218
+
This hook is like an _async-iterable-aware_ version for [`React.useEffect`](https://react.dev/reference/react/useEffect), allowing dependencies to be also computed from values yielded by the given async iterables each time, and letting the effect fire directly in reaction to particular async iterable yields rather than only just component scope values being changed across re-renders (as does the classic [`React.useEffect`](https://react.dev/reference/react/useEffect)).
1219
+
1220
+
```tsx
1221
+
useAsyncIterEffect(
1222
+
[fooIter, barIter],
1223
+
(foo, bar) => [
1224
+
() => {
1225
+
runMyEffect(foo.value, bar.value, otherValue);
1226
+
},
1227
+
[foo.value, bar.value, otherValue],
1228
+
]
1229
+
);
1230
+
1231
+
// Or if returning an effect destructor function:
1232
+
useAsyncIterEffect(
1233
+
[fooIter, barIter],
1234
+
(foo, bar) => [
1235
+
() => {
1236
+
runMyEffect(foo.value, bar.value, otherValue);
1237
+
return () => {
1238
+
cancelMyEffect();
1239
+
}
1240
+
},
1241
+
[foo.value, bar.value, otherValue],
1242
+
]
1243
+
);
1244
+
```
1245
+
1246
+
This hook is a consuming hook; any given item on the base deps array (first argument) that is async iterable will immediately start being iterated internally and continue for as long as its underlying iterable remains present in the array. Like most other hooks - plain (non async iterable) values can also be provided within the base deps at any time be conveyed as if are immediate, singular yields.
1247
+
1248
+
Whenever either of following events occur;
1249
+
1250
+
- Any of the base deps yields a value
1251
+
- Hook is called again due to component re-render
1252
+
1253
+
-> the hook will call the effect resolver function (second argument) again, providing all the last states of the actively iterated items as individual arguments corresponding to their order within the base deps array. From there, you use it exactly like [`React.useEffect`](https://react.dev/reference/react/useEffect) while having the last yields accesible to use for your actual effect dependencies and/or your effect function's logic itself. The hook supports returning from the effect function an optional function to serve as the effect tear down/destructor, like the original [`React.useEffect`](https://react.dev/reference/react/useEffect).
1254
+
1255
+
### Parameters
1256
+
1257
+
-`baseDeps`:
1258
+
An array of zero or more async iterable or plain values (mixable). In response to their yields, effect dependencies will re-evaluate and possibly fire the effect.
1259
+
1260
+
-`effectResolverFn`:
1261
+
A user-provided function to be called by the hook whenever any yield occurres, getting the last states of all the actively iterated base deps as arguments. It should return a tuple with the effect function as the first item (_required_) and the next array of dependencies as the second (_optional_). The effect function may _optionally_ itself return a function to serve as a effect teardown/destructor.
1262
+
1263
+
1264
+
### Returns
1265
+
1266
+
<ul>
1267
+
1268
+
_Nothing_
1269
+
1270
+
</ul>
1271
+
1272
+
### Notes
1273
+
1274
+
<ul>
1275
+
1276
+
> <br/>ℹ️ While you may optionally omit the dependency array in the effect resolver function's returned tuple as mentioned, note that this produces a similar behavior to calling [`React.useEffect`](https://react.dev/reference/react/useEffect) with dependencies omitted - the effect will be fired __on every re-render__ and __on every yield__ by the async iterable base dependencies.<br/><br/>
1277
+
1278
+
> <br/>ℹ️ It's important to remember that when using [`useAsyncIterEffect`](#useasyncitereffect) and [`<It>`](#it) to operate on the same async iterable, whether across components or within the same one - each of these two consumers would individually attempt to obtain an iterator from the same source iterable. Depending on how the source iterable's implementation it could lead to duplicate resources (e.g. WebSocket connections) being started. If this is undesirable, just ensure to pass that source iterable through a [`useSharedAsyncIter`](#usesharedasynciter) call anywhere along its route, ___before___ it encounters any consuming hooks like the latter ones.<br/><br/>
1279
+
1280
+
</ul>
1281
+
1282
+
1283
+
1195
1284
### `useAsyncIterState`
1196
1285
1197
1286
Basically like [`React.useState`](https://react.dev/reference/react/useState), only that the value is provided back __wrapped in an async iterable__.
0 commit comments