Some thoughts and questions about Hilla and React

Hi everyone :wave:,

React Router v7 is around for 6 months now, and I was just wondering if there are any plans to adopt some of the existing or new features?

I guess React Routers Framework Mode is less important for Hilla, because Hilla won’t directly benefit from most of the Remix stuff that was integrated in v7, right?

But what about Data Loading, for example? Wouldn’t it be nice to handle some kind of data loading/fetching outside the view/component? Less useEffect, but instead useLoaderData and less re-renderings.

Or what about the lazy loading of routes? It’s possible since 6.4 and just got an update in v7.5?

I would like to know what you think about the new Open Governance Model for React Router? There was a bit of disturbance after the blog post about Remix v3 and leaving React was published. I see this move to the Open Governance Model as a good thing and I hope this will result in an ongoing development and maintenance of React Router with React at it’s core.

Beside React Router: Hilla recently added support for React 19 behind a feature flag and according to the roadmap React 19 will become the new default in Vaadin 25. Can we expect something more of React 19 in the Framework, our is this mainly a maintenance to stay up-to-date?

What about React Compiler? Is this something that is already used in the Hilla team during the further development of the framework? Or are people in the community using it, when they build web apps with Hilla?

And last but not least, React Server Components: RSC is a huge thing in the React ecosystem. How is Vaadin thinking about it? Is this something you look at or even consider for Hilla? Or is this something that just doesn’t fit to Hilla’s architecture?

I’m really looking forward to some comments, thoughts, opinions and additions to the topic :slight_smile:

I remember having played with loaders about a year ago in feat(file-router): add support for loaders by cromoteca · Pull Request #2562 · vaadin/hilla · GitHub. There’s a discussion in the PR.

Lazy routers are implemented in 24.8: all views are now lazy except / and /login, and there’s a config parameter to change the behavior for each view.

I also had a look at RSC after atteding a great presentation at Devoxx, but we basically need stable support from Vite.

1 Like

Interesting discussion. Why didn’t you continue? Do you think, that the circumstances may have changed in the meantime?

That rings a bell. Thanks for reminding me of that ;)

Do you remember the name of the talk? Which Devvox was it? I would like to watch the recording of the talk on YouTube.

Interesting discussion. Why didn’t you continue? Do you think, that the circumstances may have changed in the meantime?

It was quite hard to achieve a good level of type safety. Also, now, with React 19, you can simplify the handling of Hilla callable methods with the use hook. So, in my opinion, the only real advantage of loaders would be the ability of throwing early, like in case of /user/1234 when user 1234 doesn’t exist.

Do you remember the name of the talk? Which Devvox was it?

Devoxx Paris 2024. The talk was in French. I guess you can easily find material on the topic anyway.

1 Like

I agree :+1: Using the new use hook for data fetching really feels like having a data loader, like in React Router.

Could it be this one: https://youtu.be/sPoo1Zwh64w ?

No, it was https://www.youtube.com/watch?v=MzmEPQFHgIk, but they are probably equivalent.

1 Like

Rather than useLoaderData, I would look for something that integrates with signals so that the loader automatically triggers again if any relevant signal value changes. I did one exploration on that topic in RFC: Signal-based view state management but I haven’t investigated that topic further since then. If we go that route, then we might eventually move away from React Router or maybe use it mainly for some low-level bookkeeping and for backwards compatibility.

Updating to React 19 is mostly a matter of staying up-to-date. There isn’t any specific new feature that we plan start using. use(Promise) looks tempting but it turns out to be quite tricky to use. That’s because it triggers Suspense which in turn leads to discarding the state of the component that was about to be rendered. This basically means that you have to use some additional mechanism to cache the promise instance so that you can get the result from it once the component renders again.

React Compiler is to my knowledge mostly a way of fixing the same things that signals help with so that’s not very relevant for typical Hilla use. RSC also doesn’t seem applicable since running JS on the server basically defeats the purpose of Hilla.

1 Like

Thanks for pointing to this RFC. Personally, I would prefer to use React Router’s way for things like View state parameters and Asynchronous view state using things like the useParams hook and the concept of loaders, because I’m more familiar with it. I understand, that you promote the usage of Signals for various aspects of the Hilla framework, and I’m sure it is a good way.

I didn’t come across this problem yet. Is this something you experienced while you were playing around with it? If this is more like a general thing, then it should only be relevant, if the component that calls use is wrapped in a Suspense boundary, right?

React Compiler can help you to follow the rules of React and the rules of Hooks. One area, where it can reduce the amount of code and/or improve the rendering performance, is memoization. When you compile your React Code using the React Compiler, it will add the required memoization to your components to avoid unnecessary re-renderings. In other words, you don’t have to use React.memo, useMemo or useCallback any more, if you want to improve rendering performance of your components.

RSC does not feel like a natural fit for a Framework like Hilla, but it has some aspects in it, that could be interesting for Hilla as well. Rendering React components on the server, could improve the performance when fetching data from a database, for example. Or it could reduce the initial load time of a view by pre-rendering the component on the server and just sending HTML to the client. But looking at these benefits as a Java Dev, it feels more like “history repeating” and I think there are already go alternatives around.

Familiarity is always hard to win against. I think there are two big benefits with the signal approach that might help overcome that obstacle. First, there can be a two-way binding so that the URL will update automatically if you change the signal value from application code. Second, it enables some additional end-to-end type safety since all parts of the system know the types of all parameters of the view (though I understand the latest version of React Router also has some limited support for this).

I tested with a pre-release and I didn’t come back to test it again with the final version so there’s a possibility that things have changed. Note that Hilla by default has a suspense boundary in the main layout to provide a fallback together with lazy loaded views so this boundary would then also catch any use inside views.

Exactly. But you don’t need any memoization for typical state cases with signals since useComputed is already automatically handling that (though there might still be some cases for useCallback).

The big question is whether the benefits would be significant enough to convince Hilla users to add a Node.js server to their production setup in addition to the regular Java server? There’s also some additional overhead and invisible delays due to rehydration, and the fact that Vaadin’s built-in components are based on web components that would anyways not be pre-rendered.

1 Like

Thanks for sharing your thoughts @Leif. Very interesting conversation.

Much of what you write gives me the impression that Hilla currently and in the foreseeable future can benefit little or not at all from extensions in React and React Router, because they either do not fit the character of the framework or are to be solved differently in the context of Signals in the future.

What will happen with Signals in Hilla? In the roadmap, I see the planned GA for full-stack signals. Do you plan to extend Signals to other areas of the framework afterwards, as you have indicated here in the thread?

UI state management is really central to everything you do in a UI framework. Once you start using signals somewhere, you get increasingly tempted to make that play nicely together with everything else.

This means that we expect to eventually have signals for routing, form binding, lazy loading and CRUD operations in addition to the collaboration angle that we’re starting with.

I can image that this feels tempting from a perspective of a creator/maintainer of a framework, but I cannot admit that I feel the same from a perspective of a user of the framework. But hopefully this will change at some point as things become more tangible and concrete.