Skip to content

Instantly share code, notes, and snippets.

@coxmi
Last active June 24, 2021 19:46
Show Gist options
  • Save coxmi/adbfc1cba5b9a39184792f3e5db92a09 to your computer and use it in GitHub Desktop.
Save coxmi/adbfc1cba5b9a39184792f3e5db92a09 to your computer and use it in GitHub Desktop.
jsx-dom self-update component

Example jsx-dom component with input fields

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)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment