Refreshes after each input event, and carries <input> between renderings, using:
{state.input.current || <input ref={state.input} />
Focus must be called manually after update:
state.input.current.focus()
| import { h, Fragment, useRef } from 'jsx-dom' | |
| import { withUpdate } from './withUpdate.js' | |
| const Example = withUpdate(({ update, ...props }) => { | |
| const state = { | |
| value : 'default', | |
| input : useRef(), | |
| ...props, | |
| } | |
| const onInput = e => { | |
| state.value = e.currentTarget.value | |
| update(state) | |
| state.input.current.focus() | |
| } | |
| return <> | |
| {state.input.current || <input ref={state.input} value={state.value} oninput={onInput} />} | |
| Value: {state.value} | |
| </> | |
| }) |
| export const withUpdate = Component => props => { | |
| const before = document.createComment('') | |
| const after = document.createComment('') | |
| const frag = document.createDocumentFragment() | |
| frag.appendChild(before) | |
| frag.appendChild(<Component update={update} {...props} />) | |
| frag.appendChild(after) | |
| return frag | |
| function update (props) { | |
| const newNode = <Component update={update} {...props} /> | |
| const parent = before.parentNode | |
| while (before.nextSibling !== after) parent.removeChild(before.nextSibling) | |
| parent.insertBefore(newNode, after) | |
| } | |
| } |