Production Patterns
Production-ready patterns with live, editable code examples
Dynamic List Management
StateAdd, remove, and update items in a reactive list
javascript•Dynamic List Management
// Working with arrays and objects in state
const items = van.state(['Apple', 'Banana', 'Orange']);
const newItem = van.state('');
const filter = van.state('');
const addItem = () => {
if (newItem.val.trim()) {
// Create new array to trigger reactivity
items.val = [...items.val, newItem.val.trim()];
newItem.val = '';
}
};
const removeItem = (index) => {
// Filter creates new array, triggering update
items.val = items.val.filter((_, i) => i !== index);
};
const clearAll = () => {
items.val = [];
};
// Derived filtered items
const filteredItems = () => {
const searchTerm = filter.val.toLowerCase();
return searchTerm ?
items.val.filter(item => item.toLowerCase().includes(searchTerm)) :
items.val;
};
return div(
{ class: 'space-y-4 p-4' },
h3({ class: 'text-lg font-semibold text-midnight' }, 'Arrays in State'),
// Add item form
div({ class: 'flex gap-2' },
input({
type: 'text',
placeholder: 'Add new item...',
class: 'flex-1 px-3 py-2 border border-mist rounded-lg',
value: newItem,
oninput: (e) => newItem.val = e.target.value,
onkeypress: (e) => e.key === 'Enter' && addItem()
}),
Button({
class: 'vwfcolor-sky solid vwfsize-md',
onclick: addItem
}, 'Add Item'),
Button({
class: 'vwfcolor-sunset outerline vwfsize-md',
onclick: clearAll,
disabled: () => items.val.length === 0
}, 'Clear All')
),
// Filter input
input({
type: 'text',
placeholder: 'Filter items...',
class: 'w-full px-3 py-2 border border-mist rounded-lg',
value: filter,
oninput: (e) => filter.val = e.target.value
}),
// Display stats
div({ class: 'flex gap-4 text-sm text-smoke' },
span('Total items: ', () => items.val.length),
span('Filtered: ', () => filteredItems().length)
),
// Reactive list rendering with filtered items
div({ class: 'space-y-2' },
() => filteredItems().length > 0 ?
div({ class: 'space-y-2' },
...filteredItems().map((item, index) =>
div({ class: 'flex items-center justify-between p-3 bg-white rounded-lg shadow-sm border border-mist' },
span({ class: 'font-medium' }, item),
Button({
class: 'vwfcolor-sunset ghost vwfsize-sm',
onclick: () => removeItem(items.val.indexOf(item))
}, '✕')
)
)
) :
div({ class: 'text-center text-smoke py-8' },
filter.val ? 'No items match your filter' : 'No items yet. Add one above!'
)
)
);▶️ Live Preview
Arrays in State
Total items: 3Filtered: 3
Apple
Banana
Orange
💡 Click "Edit Code" to modify the example
🔄 Click "Apply Changes" to see your modifications
↩️ Click "Reset" to restore original code
📋 Best Practices
State Management
• Use individual van.state() for each value
• Keep state close to where it's used
• Update arrays immutably with spread operator
• Use arrow functions for reactive values
Performance
• Debounce expensive operations
• Use keys for list items
• Avoid complex computations in render
• Clean up timers and listeners
Component Design
• Accept both props and children
• Use parseArgs for flexibility
• Provide sensible defaults
• Keep components focused
User Experience
• Show loading states
• Provide immediate feedback
• Handle errors gracefully
• Add smooth transitions