Skip to content

Instantly share code, notes, and snippets.

@chrisbuttery
Forked from anthonyshort/1.Principles.md
Last active August 29, 2015 14:16
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 chrisbuttery/9b009dc3074f74e76421 to your computer and use it in GitHub Desktop.
Save chrisbuttery/9b009dc3074f74e76421 to your computer and use it in GitHub Desktop.
import {component,dom} from 'deku'
// Define a component with a name for debugging
const Button = component('My Button')
// Define properties
Button
.prop('foo', { type: 'string', optional: true, expects: ['hello', 'goodbye'] })
.prop('bar', { type: 'boolean', default: false })
// Add middleware. These are executed in order one at a time.
Button
.use('beforeMount', store('eventTypes'), store('projects'))
.use('afterMount', afterMount)
// We can execute the middleware in tests
// Button.run('afterMount', dummyContext, checkResults)
// Button._render(dummyContext)
// Button._shouldUpdate(props, state, prevProps, prevState)
// Set the render method
Button.render(render)
// Override the shouldUpdate to increase performance.
Button.shouldUpdate(pure)
// Each hook is a pure function. The render function uses the context
// to create a virtual DOM tree. It should render the same tree every
// time given the same context.
function render(context){
let {el,children,events} = context
let {foo,bar} = context.props
let {open,enabled} = context.state
return (
<button onClick={click}>Submit</button>
)
}
// The hooks themselves could be pure and need to return the context.
// The context object could be immutable so that when you set state
// it returns a clone with the new state applied. Then we could just
// do a simple === check on the context to know if we should re-render.
function afterMount(context, next){
let {el} = context
document.body.appendChild(el)
context.setState({ 'foo': 'bar' })
next()
}
// Event handlers are also passed the context and the event object.
// They work the same way as hooks and should return the context
// object.
function click(context, next){
context.event.preventDefault()
context.setState({ foo: 'bar' })
next()
}
export {Button}
import {Button} from './button'
import {scene,render,renderString} from 'deku'
// returns a scene
var app = scene(Button)
// Set initial properties
app.setProps({ text: 'Submit' })
// Use plugins on the entire scene. Components can
// access the scene through context.scene.
app.use(channels())
// Set development mode. This will output the rendering
// and hook times for each component.
app.debug(true)
// Render the scene to the body using the DOMRenderer
// Returns the renderer object.
var mount = render(app, document.body)
// The renderer emits events whenever it updates. This is
// really only useful for updating
mount.on('update', function(){
// updated
})
// Update the props. The renderer will re-render
// the app on the next frame.
app.setProps({ text: 'foo' })
// Remove the scene and it's element from the DOM
mount.remove()
// Or render the scene to a string
renderString(app)
// Or render to canvas
renderCanvas(app)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment