-
-
Notifications
You must be signed in to change notification settings - Fork 551
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(jsx/dom): Compatible implementation of new features in React 19 (document metadata, "form" element and related hooks, and new behavior of hooks) #2960
Conversation
a58a036
to
23c9c9b
Compare
23c9c9b
to
5156416
Compare
…ity with React 19
…ity with React 19
@yusukebe I'm sorry it's such a big pull request, but could you please review it? I think this covers most of the new APIs in Ract 19. |
@usualoma Okay! I'll do it later. |
feat(jsx): improve compatibility with React 19 (precedence / specialbehavior / title)
Hi @yusukebe |
Thanks. I'm now reviewing it. |
Hi @usualoma Awesome for such a hard work! I've taken a look at the code and tried examples for the new feature with these updates. There is one issue I could find.
|
It is still a work in progress as it does not handle asynchronous errors. |
Hi @yusukebe
Each of these has been impremented. The handling of ErrorBoudnary and Suspense in general has been improved so that Please review! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Hi @usualoma Looks good to me! One thing. Can we title this PR (or a commit message with a squash merging to the main) "Introduce document metadata integration"? I think this PR does not only "document metadata matter". |
@yusukebe Thank you for reviewing! Yes, that's true. I'm sorry I put so many things in there, but if I were to describe the pull request correctly, how about this, even though it's a bit long? feat(jsx/dom): Compatible implementation of new features in React 19 (document metadata, "form" element and related hooks, and new behavior of hooks) |
That sounds good! I've updated this PR title and will merge it with the title, though GitHub will trim it. |
@yusukebe Thank you 🚅 |
…(document metadata, "form" element and related hooks, and new behavior of hooks) (#2960) * feat(jsx/dom): Introduce document metadata integration for compatibility with React 19 * test(jsx/dom): add test for "ref as a prop" * refactor: tweaks element selector * feat(jsx/dom): implement " Cleanup functions for refs" for compatibility with React 19 * feat(jsx/dom): implement `useDeferredValue()` * refactor(jsx): insert metadata into head synchronously * feat(jsx/dom): introduce form and related hooks * feat(jsx): sort by precedence in documentMetadataTag * feat(jsx): enable to specify action attribute as function * fixup! feat(jsx): enable to specify action attribute as function * refactor: refactor file layout * feat(jsx): de-dupe tags * feat(jsx): accept crossOrigin as crossorigin * feat(jsx/dom): inprement blocking and precedence feature for jsx/dom * feat(jsx): export new hooks * fix(jsx/dom): fix some bugs in jsx/dom/hooks * fix(jsx/dom): fix useOptimistic hook * fix(jsx/dom): fix signature of useActionState * fix(jsx): fix type declaration for HtmlEscapedCallback * refactor(jsx): improve importing of intrinsic element components * feat(jsx): support permalink for useActionState * fix(jsx): fix composeRef cleanup in intrinsic element components * fix(jsx): remove blocking attribute from DOM node * fix(jsx/dom): preserve HTMLElement for meta data if it will be unmounted * fix(jsx/dom): fix de-dupe logic in `documentMetadataTag` * fix(jsx/dom): fix precedence logic in `documentMetadataTag` * feat(jsx): add React 19 compatibility attributes * fix(jsx): Handle NodeListOf<HTMLElement> as an iterable * test: tweaks test data * fix(jsx/dom): fix precedence logic in `documentMetadataTag` * fix(jsx/dom): fix meta data tag insertion behavior * fix(jsx/dom): set next node recursively for all previous nodes * refactor(jsx/dom): use better variable names and types in form component * fix(jsx/dom): fix meta data tag insertion behavior * fix(jsx): improve document meta tag behavior in jsx * test(jsx/dom): add tests for intrinsic-element/components * fix(jsx/dom): fix `use()` hook wrong behavior * test(jsx/dom): add tests for hooks * test(jsx): add tests new hooks for form * fix(jsx): update current state synchronously if no actions are provided * test(jsx): add tests for new hooks for form handling * docs(jsx): add documentation for hooks * test(jsx): Update test * refactor(jsx/hooks): remove unused constant * feat(jsx): improve compatibility with React 19 (precedence / special behavior) * feat(jsx/dom): improve compatibility with title element mount/unmount behavior * feat(jsx): support async function for useTransition * fix(jsx/dom): method is always 'post' when data is present * feat(jsx): support formAction for input and button elements * feat(jsx/dom): support suspense with child counter * feat(jsx/dom): enable to handle async error in useTransition
#2959
Implemented features by this pull request
link
meta
script
style
title
Other changes or refactoring that require explanation
Some incompatibilities (in the ~18 API) were resolved in the support for React 19. Other changes not directly related to React 19 compatibility improvements are also included and are discussed below.
compatibility of
use()
hookIn hono's jsx, the following code had a behaviour where it would continue to return the result of the first promise even if a different promise was passed, which was incompatible and has been fixed.
https://github.com/honojs/hono/pull/2960/files#diff-00be452f071d90d2904b8acdd0b15dc607fee092c4545b38387e2f52a6eba35fR63-R95
compatibility of
useDeferredValue
useDeferredValue
was not implemented correctly and has been newly rewritten for compatible behaviour.The process of updating by
setState
has been simplifiedThe following 'processing in shadows' was not actually necessary and was useless code, so it was removed. I think the new way of doing things is correct, as all tests pass and no problems occur when checking in the browser.
https://github.com/honojs/hono/pull/2960/files#diff-1157fd5461da22f1e5982c5351a7f913bb8b7812d25f97c212bd7b7417344b62L192-L200
add "dom.iterable" to deno.react-jsx.json
The following code is fine in modern browsers, but TypeScript reports an error if there is no "dom.iterable" in the "libs", so I added it.
https://github.com/honojs/hono/pull/2960/files#diff-7c151a16ca64f89d875c682a551d8242736846e67198c3bc08e2802679dcaca0R119
https://github.com/honojs/hono/pull/2960/files#diff-9a67da5b07fb7e04bdbf99e1f78eca536e036cfd58553557d18fcd7b0b3da34bL7-R8
Introduce internal API
resolveCallbackSync
Added this API to insert meta data tags in the head (needed in stringify, not in dom).
https://github.com/honojs/hono/pull/2960/files#diff-fe7471a671ed7be8aefd96aacb37be7ff93c8f65c2749d64f4eb86b3c2c8e916R128-R140
We could have achieved this with Promise in the past, but this time we wanted something that could be resolved synchronously, so we added a new API in this pull request to handle it. What we are doing is almost the same as
resolveCallback
. Implemented in such a way that there is no performance deviation for existing users who use simplejsx
on the server side.The author should do the following, if applicable
bun run format:fix && bun run lint:fix
to format the code