We recently released Vaadin 24.4.0.beta1. One of the new features that we’re introducing is support for doing UI state management using signals.
Here’s how you can try that out right now. Start by downloading https://start.vaadin.com/dl?preset=react&preset=partial-prerelease, extracting it, importing it to an IDE, and running the main method in Application.java
.
You can and should use signals from @vaadin/hilla-react-signals
for state management in Hilla views. As an example, you can replace the content of @index.tsx
with a button that counts how many times it has been clicked.
src/main/frontend/views/@index.tsx
import { useSignal } from "@vaadin/hilla-react-signals";
import { Button } from "@vaadin/react-components";
export default function ClickCount() {
const count = useSignal(0);
return <Button onClick={() => count.value++}>Click count: {count}</Button>
}
The useSignal
hook is a wrapper around useMemo
to create a signal instance that is bound to the life cycle of the rendered React component instance.
Sharing signal instances
You can also define a signal with a longer life cycle but you should then be careful to do it outside the React render function so that you don’t create a new instance every time the component is rendered. You should use the signal(<initial value>)
factory function rather than the useSignal(<initial value>)
hook when creating signal instances outside React render functions.
Furthermore, you can export the signal instances so that they can be used by other client-side parts of the UI.
src/main/frontend/views/@index.tsx
import { signal } from "@vaadin/hilla-react-signals";
import { Button } from "@vaadin/react-components";
export const count = signal(0);
export default function ClickCount() {
return <Button onClick={() => count.value++}>Click count: {count}</Button>
}
This signal instance can then be imported in some other component, e.g. the main layout. (This is a nonsensical example since it makes the layout depend on a specific view but it’s still a simple way of showing the point.)
You can edit the main layout to show the click count next to the title of the current view. (Not showing the full file here since it’s long-ish.)
src/main/frontend/views/@layout.tsx
(partial)
import { count } from './@index';
// Further down inside the render function:
<h2 slot="navbar" className="text-l m-0">
{currentTitle} {count}
</h2>