Skip to content

Instantly share code, notes, and snippets.

@AutoSponge
Last active May 30, 2017 02:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AutoSponge/722f0276f2da4e0a8506182a5910cb0a to your computer and use it in GitHub Desktop.
Save AutoSponge/722f0276f2da4e0a8506182a5910cb0a to your computer and use it in GitHub Desktop.
set-state-html
import { h, Component } from 'preact'
import style from './style'
import state from 'set-state'
const toInteger = n => (isNaN(n) ? 0 : parseInt(n || 0, 10))
// raw count state with default
const count = state(0)
// collects events used to set count
const setCount = state()
// projection of count as integer
const $count = count.map(toInteger)
// collects events used to increment count
const inc = state()
// plucks the new value from the event
setCount.pluck('target.value').on(count)
// increments the current count
inc.on(() => count($count() + 1))
// you can manipulate this from the console to trigger re-render
window.count = count
class StatefulInput extends Component {
componentDidMount () {
const { value } = this.props
this.cancel = state.combine({ value }).on(this, 'setState')
}
componentWillUnmount () {
this.cancel()
}
render (props, state) {
return <input {...props} {...state} />
}
}
export default class Home extends Component {
render () {
return (
<div class={style.home}>
<h1>Home</h1>
<StatefulInput
class={style.stateful}
onInput={setCount}
value={$count}
/>
<button class={style.stateful} onClick={inc}>add 1</button>
</div>
)
}
}
const morph = require('nanomorph')
const html = require('bel')
const state = require('set-state')
const root = document.body.appendChild(html`<div></div>`)
const toInteger = n => (isNaN(n) ? 0 : parseInt(n, 10))
const count = state(0)
const setCount = state()
const $count = count.map(toInteger)
const inc = state()
const oninput = e => setCount(e)
setCount.pluck('target.value').on(count)
inc.on(() => count($count() + 1))
// you can play with the state in the console
window.count = count
count.on(console.log.bind(console, 'value:'))
const input = props =>
state.combine(props)
.reduce((from, {value, oninput}) => {
const to = html`<input ${{value, oninput}}>`
return morph(from || to, to)
})
.valueOf()
morph(
root,
html`
<div>
${input({ value: $count, oninput })}
<button onclick=${inc}>add 1</button>
</div>
`
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment