Trying out signals in Vaadin 24.4 beta1

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>
4 Likes