Skip to content

Instantly share code, notes, and snippets.

@sergey-shpak
Last active July 19, 2023 19:35
Show Gist options
  • Save sergey-shpak/dffb81833fa060ec81d5830a9a039f82 to your computer and use it in GitHub Desktop.
Save sergey-shpak/dffb81833fa060ec81d5830a9a039f82 to your computer and use it in GitHub Desktop.
Hyperapp#v2 Stateful component
import { app, h } from "hyperapp";
import { Stateful } from './helpers'
/* Working example, https://codepen.io/sergey-shpak/pen/maMopd */
// --- STATEFUL COMPONENT ---
// Don't use arrow functions for stateful components/actions
// Since context is linked to it's definition context
// Don't forget to return new state to trigger view re-render
// You can get local component state as function context (this)
// In all other senses it is a typical component. Enjoy!
function onFocus(state){
this.focused = true
return { ...state }
}
function onBlur(state){
this.focused = false
return { ...state }
}
function Input(props, children){
return [
h('input', {
onFocus: onFocus.bind(this),
onBlur: onBlur.bind(this)
}),
h('div', {}, `Focused ${this.focused}`)
]
}
// Exposing initial component state
Input.state = { focused: false }
// --- USAGE EXAMPLE ---
// Init stateful component (with default state)
const InputBox1 = Stateful(Input)
// or you can override initial component state
const InputBox2 = Stateful(Input, {
focused: true
})
app({
init: {},
view: () => h('div', {}, [
h(InputBox1, {}),
h(InputBox2, {}),
]),
container: document.body
})
/*
This is implementation of Hyperapp#v2 stateful components
Helpful when you don't want to expose internal component state
or you want to create a simple and re-usable component
*/
export const Stateful = (Component, state) =>
Component.bind(state || Component.state || {})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment