Comments (14)
@Zolmeister
May I ask what output the following demo should have according your proposal?
https://codesandbox.io/s/intelligent-moser-c4cjt
from dyo.
@mcjazzyfunky Because yield now only represents control-flow, the output would be:
ignored-1
ABC
ignored-2
ignored-3
from dyo.
@Zolmeister What's the difference new Set(['A', 'B', 'C'])
and the others? They both produce sync iterators. Why treat them differently?
from dyo.
Oh, yes. My mistake. It would not have ABC (it would be undefined
)
ignored-1
ignored-2
ignored-3
from dyo.
Thanks for the responses.
Actually I think new Set(...)
and function* () {... }
should really be treated differently because they are indeed quite different. A set is an iterable (I do not know whether that's the correct ES201x term - but I think you know what I mean) as it has a property someSet[Symbol.iterator]
while generator functions do not have such a property (only the return value of a generator function, the iterator, has a [Symbol.iterator]
property)
So I think there are good reasons that the result of my demo should indeed be:
ignored-1
ABC
ignored-2
ignored-3
Otherwise the whole support for iterables (except for arrays) in Dyo would be killed.
Using collections/iterables other than arrays would require an explicit iterable to array
conversion (using Array.from(...)
or whatever).
For example something like the following would not be supported out of the box any longer:
https://codesandbox.io/s/purple-sound-v737x
(in this particular case you would have to convert the lazy sequence to an array explicitly before using it as a child node)
from dyo.
@Zolmeister In your example:
function* Component() {
a = yield* useHook()
return h('div', a) // <div>xxx</div>
}
You wouldn't need async generator component to archive this, normal async components work fine.
async function Component() {
const a = await useHook()
return h('div', {}, a)
}
or raw promises
function Component() {
return h('div', {}, useHook())
}
Async generators allow you to render multiple states:
async function* Component() {
yield 'Loading...'
const a = await useHook()
yield h('div', {}, a)
}
Which would first render 'Loading...' immediately, then after the useHook has resolved render the div, async generators are uniquely unlike normal async components or normal sync generators.
from dyo.
@thysultan Unfortunantely due to the mechanics of hooks, normal async components are crippled (ref #111).
e.g.
async function* Component() {
yield 'Loading...'
const a = await useHook()
// TypeError: Cannot read property 'owner' of null
const b = await useHook()
yield h('div', {}, a, b)
}
Therefore you will almost always want to use the generator style when handling inline-promises.
@mcjazzyfunky I can get behind that. Function components that return generators should be treated differently than generator components.
from dyo.
Why are the hooks interlaced like that instead of:
async function* Component() {
const a = useHook()
const b = useHook()
yield 'Loading...'
yield h('div', {}, await a, await b)
}
from dyo.
@thysultan If the hook is async, you can only have one (regardless of interlacing). Some of my hooks are async.
async function* Component() {
const a = await useHook()
// TypeError: Cannot read property 'owner' of null
const b = await useHook2(a)
yield 'Loading...'
yield h('div', {}, a, b)
}
Edit: I see, you await at the end. Imaging the value from one hook needs to be passed to another.
from dyo.
@Zolmeister I still don't understand, when you use hooks like that you are going against the call order rule of hooks. It is the equivalent of using hooks in a for-loop?
What exactly are you trying to do with the useHook
hook?
from dyo.
@thysultan
This may be quite an unpleasant question but are you really sure that these "async generator function components" and "promises as elements" features are actually good ideas?
Are there really non-trivial "async generator function components" that behave in a way someone would like? For example when the parent component will be updated but the changes are actually not relevant for the inner async generator function component then the promises inside of the async generator function will nonetheless start to be resolved again.
The following three demos for example do not behave like as I would expect or as I would like:
(1) https://codesandbox.io/s/flamboyant-wescoff-69ri3
(2) https://codesandbox.io/s/bold-rubin-x63s8
(3) https://codesandbox.io/s/romantic-snyder-esuvo
This demo shows a behavior as I would expect:
(4) https://codesandbox.io/s/silly-snowflake-tmrhx
from dyo.
@thysultan that's a good point, call-order might break subtly. e.g. getting this to work might be tricky:
X = ->
useState()
yield Promise.delay(Math.random() * 100)
useState()
h 'div', X, X, X
My initial purpose for this feature was to allow hooks which are 'sync' server-side but 'async' client-side. e.g.
useStream = (fn) ->
return if window?
useResource(fn)
else
useMemo fn, []
X = ->
user = yield useStream(-> fetch '/user')
[counter] = useState(0)
However, after some consideration (especially given the comments by @mcjazzyfunky #113 (comment)) I think this is not an efficient approach. I'm closing #114, however I still think this feature is interesting and worth considering.
from dyo.
@mcjazzyfunky I agree some of the demo's present unexpected behaviour.
'sync' server-side but 'async' client-side
@Zolmeister async works just as well server-side.
useResource can be considered a sync hook since it uses suspense/caching + throwing a promise, so it acts like a sync hook, meaning your example wouldn't need async/yield, unless i'm missing something?
X = ->
user = useStream(-> fetch '/user')
[counter] = useState(0)
We could relegate async/promise
values to act like the useResource
hook that works with Suspense
.
from dyo.
@thysultan excellent point. I forgot we actually have async
hooks via Suspense
(a bit leaky, but good enough).
The call-order issue #113 (comment) I think makes this proposal a non-starter. I'm going to close this issue, thanks everyone for the feedback.
from dyo.
Related Issues (20)
- Async generator return value as result tree HOT 7
- Deep Suspense and Server Side Rendering
- Replacing Pure Components HOT 9
- Improving useResource
- why use rAF of useEffect but not setTimeout HOT 6
- JS.ORG CLEANUP
- No issue - just an idea that may be discussed: Splitting Dyo core from Dyo non-essentials HOT 7
- Exception message not a string HOT 2
- Reconciliation with children and innerHTML across updates HOT 4
- useEffect slower than React HOT 2
- child-array re-use error HOT 14
- SVG rendering by generators (or array) is broken (namespace context information not propagating) HOT 6
- Is it really a good idea to support generator function components and iterators/generators as virtual node in general? HOT 16
- About immutable virtual elements HOT 2
- About scheduler and fibers in Dyo HOT 3
- Better support for custom elements HOT 15
- Strange delay when using suspense HOT 7
- Better support for custom elements (additional issue) HOT 16
- Problems when nesting Suspense elements HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dyo.