Skip to content

Handle Events and State

React state works the way you expect. Uzumaki supplies the elements and the event objects.

function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount((value) => value + 1)}>
<text>Clicked {count} times</text>
</button>
);
}

Pointer events include coordinates and button state:

<view
onMouseDown={(event) => {
console.log(event.x, event.y, event.button);
}}
/>

Use onValueChange for the current value:

const [query, setQuery] = useState('');
<input
value={query}
onValueChange={setQuery}
placeholder="Search"
px={12}
py={10}
rounded={10}
/>;

Use onInput when you need event details:

<input
value={query}
onValueChange={setQuery}
onInput={(event) => {
console.log(event.inputType, event.data);
}}
/>
const [enabled, setEnabled] = useState(false);
<checkbox checked={enabled} onValueChange={setEnabled} />;

Elements can handle keyboard events when they can receive focus:

<view
focusable
onKeyDown={(event) => {
if (event.metaKey && event.key === 'k') {
event.preventDefault();
openCommandMenu();
}
}}
/>

UI events also bubble to the window, which is useful for global shortcuts:

window.on('keydown', (event) => {
if (event.ctrlKey && event.key === ',') openSettings();
});
window.on('load', () => {
console.log('window loaded');
});
window.on('resize', (event) => {
console.log(event.width, event.height);
});
window.on('close', () => {
console.log('window closed');
});
<button
onClick={(event) => {
event.stopPropagation();
event.preventDefault();
}}
>
<text>Do not bubble</text>
</button>

Use preventDefault() for native default behavior. Use propagation controls when parent handlers should not run.