painting-and-drawing-tools-set-207665

Google Web Toolkit (GWT) is a mature framework, stable and reliable, used in many large projects. However, seems as if it is exiting the spotlight in modern web development. In the past few years, there were just a few official GWT releases and many GWT apps have been rewritten by using other solutions. In this text, we will try to describe the integration (not full replacement) of GWT and some modern JavaScript, for example React.

React is one of the most popular technologies for building user interfaces today. One of the major advantages of integrating React with existing technology is simplicity. If you just want some small part of the application rendered in React, it is quite possible. Even on the official React website, there is a tutorial on how to execute integration with React (for more details, check out React)


Creating a new application 

1. React

The best way to create a React app from scratch is to use Create React App. With this tool, you can produce a simple, single-page React app without any configuration. Subsequently, you may add some amendments in JSX code to obtain the final look you desire.

The entry point of application can be found in index.js and index.html. In the js file, you may see that the application will render React components and place them into document element with id "root". The aforementioned div element is defined in index.html

Instead of rendering app in div with "root" ID you should expose a function so it could be called outside. This function should render app at the desired place as you may see in our example below: 

And that's it. Now React application will be rendered on a defined call and placed in the desired document element (some document element in the outside application). Additionally, you need to edit the GWT code so it would call the function and place React code in its HTML.

2. GWT

On the GWT side, let's suppose you have a new panel dedicated to the React app. There are a few things you should set up to successfully integrate React, as you may see in the following snippet of code.

The most important thing in the above mentioned code is that this new panel is overriding onLoad() method from GWT Widget class. As suggested in the GWT documentation: "This method is called immediately after a widget becomes attached to the browser's document." Excellent place for integrating with some external js code.

renderedComponent method is called with id as parameter and it is annotated @JsMethod(namespace = JsPackage.GLOBAL). The annotation came from the JsInterop GWT feature. It says that the aforementioned method will be directly translated into JavaScript method preserving its name so it is crucial for the name to be same as previously created in React and exposed to the global window variable (learn more about JsInteroop on the following link: JsInterop)

With this construction, we have achieved that publicly exposed function window.renderComponent is called with "react_app_id" argument and that function will render the React app. A small part of code in the constructor is just here to respond in the window width parameter and force the content panel to fit in our application.


Integrating new code

1. React

Upon the described modification, we need to build and include React code in the GWT application (for now they are separated in their projects). First thing is to make React application production-ready by building it. This operation will populate the build folder with a production code of your application. Everything we require is located inside build/static folder. The aforementioned folder contains separated JS and CSS files with unique filename created as hash of content. You should keep in mind that files will modify their names after building some additional changes.

2. GWT

On the other side, the GWT application should include production files described in the previous section. To achieve this you need to edit src/main/webapp folder. Create a new folder structure named scripts/react and just copy CSS and JS folders from React build inside.

Afterwards, main HTML application should be edited to include copied files. Importing React dependency is a mandatory step as well.

Now you should be able to see React application running in GWT code after loading ReactPanel class.


What's next

You could establish communication between React and GWT. For example, if you need to have a response in GWT for some actions in React and vice versa. You can simply create dedicated classes/functions for that kind of communication.

1. React

As previously seen, the public function has to be exposed as a global function to be called from GWT.

When a user changes the date in React application, this function will execute a call to global method. The same function name will be just declared in GWT.

2. GWT

In the GWT part of code, we create one dedicated class for communication. This class describes the JavaScript API of an object. Some methods are accessible from outside JS and some already exist in JS and, in our case, in React code. In order to work properly, the names of JS members need to be unique.

We can see two different types of methods in this class, for example two different types of usage of the JsInterop GWT feature. The first one is setParameters method. This exposed Java type will be accessible from the external JS script. In order to call the method, you need to specify name exactly as described with annotations.

Another way to use JsInteroop feature for methods is to import an external script to be called from Java code. To do that, the method needs to be public static native. Calling this method from Java code will call JS function dateChangeHandler(date).

Conclusion 

We have achieved integration of React component with GWT application, with some small changes on both sides. With this procedure, we will be able to easily remove some obsolete parts of GWT application and create React components to replace them, maybe by introducing some new powerful React UI libraries.