Skip to content

Conversation

@reznord
Copy link
Member

@reznord reznord commented Jul 8, 2020

Use the vnode to get access the DOM node (for getting the current element).

@developit 's magic 😄

Fixes #1293

@reznord reznord requested review from developit and prateekbh July 8, 2020 20:42
@developit
Copy link
Member

note: I haven't tested this yet, not actually sure if it works. It's also scary.

@reznord
Copy link
Member Author

reznord commented Jul 8, 2020

I did test this out on all the possible demos 😁

Copy link
Member

@prateekbh prateekbh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see the flash again because of this PR. I'll find a way to add a test around this tonight

developit added a commit that referenced this pull request Jul 9, 2020
I finally (FINALLY) found a solution for #1293, #1308, etc etc. This doesn't use DOM hacks or anything - it just crawls up the tree of VNodes and performs a Depth-First-Search backwards from the position of AsyncComponent in order to find the most recently hydrated DOM element. Essentially, the first populated `vnode._dom` reference it finds is guaranteed to be the previous sibling of the parent element AsyncComponent is about to get rendered into. As long as AsyncComponent isn't being used load a component that renders a Fragment, the nextSibling of that discovered element is the exact node Preact will try to hydrate.

In the case of an AsyncComponent wrapping a Fragment, only the first Fragment child will be hydrated. This means the remaining children will have the flicker effect, but that's pretty reasonable:

```js
// app.js
import Foo from 'async!./foo';
export default () => <div><Foo /></div>

// foo.js
export default () => <Fragment>
    <h1>Hello</h1>
    <p>world!</p>  // will be culled+reinserted during hydration
</Fragment>
```
@reznord
Copy link
Member Author

reznord commented Jul 9, 2020

Closing this in favour of #1309

@reznord reznord closed this Jul 9, 2020
reznord added a commit that referenced this pull request Jul 9, 2020
* Fix async-loader for Preact X

I finally (FINALLY) found a solution for #1293, #1308, etc etc. This doesn't use DOM hacks or anything - it just crawls up the tree of VNodes and performs a Depth-First-Search backwards from the position of AsyncComponent in order to find the most recently hydrated DOM element. Essentially, the first populated `vnode._dom` reference it finds is guaranteed to be the previous sibling of the parent element AsyncComponent is about to get rendered into. As long as AsyncComponent isn't being used load a component that renders a Fragment, the nextSibling of that discovered element is the exact node Preact will try to hydrate.

In the case of an AsyncComponent wrapping a Fragment, only the first Fragment child will be hydrated. This means the remaining children will have the flicker effect, but that's pretty reasonable:

```js
// app.js
import Foo from 'async!./foo';
export default () => <div><Foo /></div>

// foo.js
export default () => <Fragment>
    <h1>Hello</h1>
    <p>world!</p>  // will be culled+reinserted during hydration
</Fragment>
```

* Stop searching if we hit an element parent

Co-authored-by: Anup <[email protected]>
@ForsakenHarmony ForsakenHarmony deleted the async-loader-current-node branch September 2, 2020 00:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot import async components: Undefined component passed to createElement()

4 participants