Two-way binding keeps application state and the DOM synchronized: state changes update the interface, while interface changes update state through events. section 6.3.3 section 6.4
A small input binding separates the mechanism into two responsibilities:
- Render the current state through the input’s value attribute. section 6.3.3
- Listen for input events and dispatch the new value so a reducer updates state. section 6.3.3
Binding a TODO input
Set value to state.currentTodo, then emit update-current-todo with target.value whenever the user types. The renderer applies the updated state back to the input. section 6.3.3
Listing 6.5 The CreateTodo() component (todos.js)
function CreateTodo({ currentTodo }, emit) { #1
return h('div', {}, [
h('label', { for: 'todo-input' }, ['New TODO']), #2
h('input', {
type: 'text',
id: 'todo-input',
value: currentTodo, #3
on: {
input: ({ target }) =>
emit('update-current-todo', target.value), #4
keydown: ({ key }) => {
if (key === 'Enter' && currentTodo.length >= 3) { #5
emit('add-todo') #6
}
},
},
}),
h(
'button',
{
disabled: currentTodo.length < 3, #7
on: { click: () => emit('add-todo') }, #8
},
['Add']
),
])
}
Inspect the complete CreateTodo component, including the bound input, event handler, Enter-key behavior, and Add button. section 6.3.3

