feat(jsx/dom): improve compatibility with React
#2508
What is this?
Improve compatibility with React and make the Getting started level code work for the following UI components
https://github.com/honojs/hono/assets/30598/c86423d3-90d0-4296-8ae4-ff90a5432188
by https://github.com/usualoma/hono-react-compat-demo
Simple usage
tsconfig.json https://github.com/usualoma/hono-react-compat-demo/blob/main/tsconfig.json#L22-L28
vite.config.ts https://github.com/usualoma/hono-react-compat-demo/blob/main/vite.config.ts#L5-L8
You can use /hono/jsx
It is better to use hono/jsx/dom in terms of performance, but simply specifying hono/jsx works just as well.
tsconfig.json
"paths": {
"react": ["./node_modules/hono/dist/jsx"],
"react-dom": ["./node_modules/hono/dist/jsx/dom"],
},
vite.config.ts
alias: {
'react': 'hono/jsx',
'react-dom': 'hono/jsx/dom',
},
New staffs
The following React compatible staffs are now exported from hono/jsx and hono/jsx/dom
createRefforwardRefuseImperativeHandleuseSyncExternalStore
These staff are also exported from hono/jsx/dom.
flushSynccreatePortal
Children
Implement Children API
https://react.dev/reference/react/Children#alternatives
CSS custom properties in style attribute
CSS custom properties can now be exported.
<div style={{"--my-custom-property": "10px"}}>{children}</div>
defaultProps
defaultProps is an old API, but there seems to be a library that uses it, so it is supported
https://legacy.reactjs.org/docs/react-component.html#defaultprops
Bug fixes
Various bugs have been fixed, such as the behaviour when deleting Elements.
Compatibility with [email protected]
There are no breaking changes from v4.2.7. However, the internal structure has been significantly refactored and there is a possibility of unintended incompatible behaviour, so please check the behaviour of your application when updating.
Author should do the followings, if applicable
- [x] Add tests
- [x] Run tests
- [x]
yarn denoifyto generate files for Deno
@usualoma
Coooool! I've tried your repo, it works great!
@yusukebe Thanks for confirming. Tests have been added and are ready for merging!
Hi @usualoma !
I'll merge this into the "next" branch! The next minor version will be released soon.
Was able to integrate https://ui.shadcn.com/docs/components/calendar#form as an island with the above setup and 4.3.6. Picking works. The toast part doesn't yet.
I might horribly be disoriented if the below is a missing piece, but let me share my poc:
attachReactJsxNode.tsx:
import { useEffect } from 'hono/jsx'
import { render } from 'hono/jsx/dom'
// import { v4 as uuidv4 } from 'uuid'
// import { nanoid } from 'nanoid/non-secure';
export function attachReactJsxNode (
jsxNode: JSX.Element // shall come from island or an other "browser-time" component
) {
const mountPointId = _randomId() // uuidv4() / nanoid()
useEffect(() => {
console.log('mounting a react-like component')
render(jsxNode, document.getElementById(mountPointId)!)
}, [])
return <span id={mountPointId} style={{display:'content'}} />
}
// if no random id lib used, then:
function _randomId () { return Math.random().toString(36).replace(/^0\./, '_') }
UPD: renamed from mount... to attach... which is more browser-like, plus mount is already used by hono in a different context
Demo
From: https://ui.shadcn.com/docs/components/tooltip In islands:
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger,}
from '@/components/ui/tooltip'
import { attachReactJsxNode } from '@/browser/attachReactJsxNode'
export default function TtDemo () {
const tt =
<TooltipProvider>
<Tooltip>
<TooltipTrigger>Hover</TooltipTrigger>
<TooltipContent>
<p>Add to library</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
return attachReactJsxNode(tt)
}
(I still struggle with styles, but that must be my parallel tailwindcss v4-alpha experiments.)
Hi @timurxyz
If you still think you want the feature/fix, can you create another issue?
My experiment with getting tamagui to show at least a button in the faked react was blocked by the currently missing useInsertionEffect.
OK, I'll take a look.
tooltip, useInsertionEffect