React Components in Vaadin Framework

Nuno Grilo Pinheiro
5 min readJul 18, 2016

--

While I was telling a friend that react was pretty cool they asked me “Can I use it in Vaadin?”. I saw an opportunity to do an interesting research.

React and Vaadin are two things that at first sight do not make sense together. In React we develop fully in client-side while making some HTTP calls to a backend. In Vaadin we develop everything on the server-side, components are magically rendered for us on the browser and RPC calls are invisible to us.

But the main reason why we develop components is to be able to reuse them. There may be a scenario in which you have a React component which performs lots of domain logic and you want to use it in a Vaadin view instead of replicating its logic. Imagine for instance your company standard signup form created in react, which is used in all your applications, either React or Vaadin. Instead of recreating it in Vaadin, you would allow all the logic to be performed by the React client-side and somehow communicate to Vaadin the signup result.

The proof of concept — It works

Integrating a React component into Vaadin is easy but requires some knowledge.

Since React “is simply” Javascript, you can use it in Vaadin through Javascript components as you would integrate any other client-side library. You can check it in Vaadin documentation.

I created a simple React component, which says “hello, <name>” and allows you to fill a new name and submit it. I created a Kotlin class which is a Vaadin AbstractJavascriptComponent and represents this React component on the server-side.

To finish, I created the Javascript connector, which initiates the React renderization and delegates the new name submission to the server. You can check that in the first commit of my repo.

Too Much Work

Although the description makes it seem almost effortless, this process is prone to errors, and if you are creating a component with several fields/handlers, it may be a time consuming and boring process.

So I thought this could be taken one step further: Instead of writing all this code ourselves, let’s generate the Vaadin component automatically based on the React component meta-information (proptypes).

This is not a novel idea, the Vaadin team is using this approach to enable Polymer components in GWT and in the future you will probably see them using it to Vaadin itself.

The Generator Steps

I created the generator, which you can check on the vaadin-react repo.

The generator performs the following steps

1 — Parse the desired components (defined in a json file) — This step is performed through react-docgen, a Facebook solution which can read the information from a React component

2 — Generate the Vaadin component which can be used to instantiate the React component

3 — Generate the Javascript connector

4 — Browserify the connector to enable using the component without further steps.

The current project version expects a maven and npm mixed project, so the resources will be ready to use in your maven generated-sources folder.

Optimizing Static Resources

If you are just using one react component, and just use it in a specific part of your application, the previous solution is enough and you can simply use ComponentImpl to instantiate it.

But in most cases you will probably want to optimize your resources. The browserified connector generated is fat, it contains not only the component but also the whole React framework, React-DOM, etc. This can lead to some duplication: If you are using more than one component, some libraries such as React will be loaded more than once, and may even lead to runtime conflicts on the client-side.

Even if you are using only one component, you may be running your Vaadin application in embedded mode inside a page that already contains React. In this case your component should be using the React framework already present on the global scope.

As a forecast to such situations, the current generator generates two different classes, a Component_Base class which has all the methods representing the client-side component, and a ComponentImpl class, which inherits from the Base class. The only feature the Impl class adds is the fetching of the browserified resources. So, if you don’t want to use the browserified connector, you simply create a new component class, inheriting from the Base, and add the @Javascript annotation to load only the thin connector and your component. You can get and adjust the connector from target/classes/<package>/ComponentSimpleConnector.js

@Javascript(“adjustedConnector.js”, “Component.js”)public class MyComponent_Lean extends MyComponent_Base{
}

If you have multiple components, and are not in an embedded view already containing React, you can also browserify all the files together and add the generated file as a dependency to your Vaadin UI using the @Javascript annotation

@JavaScript({ “react-components-bundled.js”})
public class MyUI extends UI {

}

Limitations In Functions

If a React component expects a function, the generated field will be a JavaScript function, a functional interface which method accepts a JsonArray. This means that functions can be called from client world to server world. But such a call has a simple limitation : It cannot return any value.

If calling a server function could return a value, this would mean that the client would be blocked until the answer was retrieved which could take up to seconds in bad network conditions, hence this limitation.

This does not imply that functions are useless. If we are talking about a function to render an element (for instance in a grid), it will not work. But in the case of notify functions, for instance, to warn that the user has submitted a form and provide its data, then this function can be used. This is the case of the simple sample in the repo.

Wrap Up

Mixing up Vaadin with React may not be something you require everyday, but is not something you need to avoid if re-using a React component would help you. This project can help you by generating most of the code you need for such an errand.

Although the generator helps in the creation of the classes, you may still have some work optimizing your Javascript resources.

I also assume that most of the time you won’t simply use a react component out of the box. You may need to create a new wrapper component to setup some client side logic before creating the component for Vaadin, for instance to implement some required functions.

React-docgen, the tool used to parse the components, is really sensitive, and it may be unable to get some components. Test using the project in your components to check if the meta-data is being properly calculated.

Please tell me what you think about this project, would you like it to grow into a solid piece or should it sink? Its survival will rely in community interest.

--

--