Skip to content

Instantly share code, notes, and snippets.

@sergey-shpak
Created June 29, 2019 12:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sergey-shpak/c1e0db3d52019eecb0b5717e8cbf00ad to your computer and use it in GitHub Desktop.
Save sergey-shpak/c1e0db3d52019eecb0b5717e8cbf00ad to your computer and use it in GitHub Desktop.
Hyperapp#2 lifecycle events helper
import { h } from 'hyperapp'
import Lifecycle, { withChildLifeCycle } from 'lifecycle'
// 'customEvent.detail' contains element triggered lifecycle event
// please use effects to properly manipulate dom element
const action = (state, customEvent) => state
// and somewhere
<Lifecycle>
<div oncreated={ action }>created</div>
</Lifecycle>
// or
{ withChildLifeCycle(<form>
<input type="text" oncreated={ action } />
</form>) }
import { h } from 'hyperapp'
const wrap = (method, eventName) => function (el){
const event = new CustomEvent(eventName, { detail: el })
setTimeout(() => el.dispatchEvent(event))
return Object.getPrototypeOf(this)[method].call(this, el)
}
export const withChildLifeCycle = node => {
return { ...node, props: {
appendChild: wrap('appendChild', 'create'),
removeChild: wrap('removeChild', 'remove'),
...node.props
}}
}
export default (props, child) =>
withChildLifeCycle(<div {...props} >{ child }</div>)
@websemantics
Copy link

websemantics commented Oct 9, 2019

Thanks for providing this answer. It took me the morning to arrive here :)

I'm including a working example for those new to hyperapp like myself,

  • index.html, I'm using hyperapp@2.0.1 so I had to change event name to camel case, onCreate
<html lang="en">

<head>
    <!-- Source @ https://gist.github.com/sergey-shpak/c1e0db3d52019eecb0b5717e8cbf00ad -->
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Life Cycle</title>
    <script type="module">
	import {h, app} from "https://unpkg.com/hyperapp?module"
	import { withChildLifeCycle } from './lifecycle.js'

	const changeInputValueEffect = (el) => { el.value += ' Ipsum' }
	const onCreate = (state, customEvent) => [state, changeInputValueEffect(customEvent.detail)]

	app({
		node,
		init: {
			value: 'Lorem'
		},
		view: state => withChildLifeCycle(
			h('form', {}, [
				h('input', {type: 'text', value: state.value, onCreate})
			])
		)
	})
    </script>
</head>
<body>
    <div id="node"></div>
</body>
</html>
  • Included lifecycle.js to avoid jsx build step (last export)
import {h} from "https://unpkg.com/hyperapp?module"

const wrap = (method, eventName) =>
  function (el) {
    const event = new CustomEvent(eventName, { detail: el })
    setTimeout(() => el.dispatchEvent(event))
    return Object.getPrototypeOf(this)[method].call(this, el)
  }

export const withChildLifeCycle = node => ({
  ...node,
  props: {
    appendChild: wrap('appendChild', 'create'),
    removeChild: wrap('removeChild', 'remove'),
    ...node.props
  }
})

export default (props, child) => withChildLifeCycle(h('div', props, child))

@websemantics
Copy link

Also see, hyperapp-lifecycle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment