Migrating Sencha EXTJS to ReactJS
Migrate from Sencha EXTJS to ReactJS in a few, simple steps.
Join the DZone community and get the full member experience.
Join For FreeHTML, CSS and JavaScript are the backbone of websites all over the internet. JavaScript is composed of several libraries that are used to add dynamic effects and responses to websites. It has a bundle of various libraries to its name including Node.js, React.js, Nativescript, and so on.
Companies are now racing to migrate and shift all capabilities of their platforms from Extjs to ReactJs with the same libraries and nodes.
The good news is that React.js is a free open source software with several different contributors to its community that renders it always functional. For users who have become familiar with Ext JS, they can find platforms like Modus that provide experts and resources that can assist with the migration process.
You may also like: React.js Essentials.
The Advantage of Using React
React grew out of the development circles of Linux and Javascript coders who wanted to create an extension of the software that could perform all the activities in exemplifying and streamlining the processes of web development as well as software development. So what makes React such a huge deal?
The ReactJs environment provides ample space to set up resilient or agile projects. This minimizes the need for debugging, reduces chances of connectivity hurdles, and allows for more natural alterations in the future. But there are a bundle of other advantages that make React development an essential addition to the Javascript library, like:
- To begin with, it is simple, mighty and is equipped with an API that has an active community, as well as an existing database of coders and debuggers.
- Having been developed with an MIT license, it’s continually being updated and improved over time as well as being equipped with changes that make it useful for developers all across the globe.
- The software is equipped with a robust companion library that makes it extremely compatible with mobile app development and also suitable for cross-platform development.
- One of the biggest challenges with app development and web development is the migration of some aspects from older systems to newer platforms. With React, such transitions become more comfortable and time-efficient in both the debugging process and agile development.
- Users familiar with VSCode and Docker would find themselves at home when using React, as it is developed from an ecosystem built upon modern CSS and JavaScript libraries. It is simple, flexible, and allows for more natural improvements across all networks.
Using Alternatives to Extjs
The complete migration of Sencha Extjs components may seem complicated and time consuming, especially from one frontend framework to another, but a possible solution to it exists: first develop a framework that uses domain logic spread in Ext and then imports all views and controllers.
Let’s take a look at a sample application that uses Extjs as its user interface and runs on C# as the backend. The application is devoid of ecosystems like Grunt, Gulp or any node package managers. The Sencha commands are used to reduce workloads and create new modules without much dependence on Extjs. One of the possibilities to use instead of Extjs is to employ iframes. The following is a sample code for an Extjs view with an iframe:
Ext.define('App.view.utilities.desktop.ReactWindow', {
extend: 'Ext.form.Panel',
alias: 'widget.App_view_utilities_desktop_ReactWindow',
bodyPadding: 5,
width: 600,
layout: {
type: 'vbox',
align: 'stretch'
},
initComponent: function() {
var me = this;
var dynamicPanel = new Ext.Component({
autoEl: {
tag: 'iframe',
style: 'border: none',
src: me.url
},
flex: 1
});
Ext.apply(me, {
title: 'React',
defaults: {
labelWidth: 120
},
items: [dynamicPanel]
});
me.callParent();
}
});
On triggering the iframe, the user can add the code for the following panel to the desktop:
this.addPanel(Ext.create('App.view.utilities.desktop.ReactWindow', {
url: 'react/mod/someurl/'
}));
[GUI]
* global.asax
* default.aspx
**** [app] -> extjs
**** [react] -> reactjs
Moving On To React Components
With the iframe in deployment, users can now open new Ext panels from within the React sub-application by inserting custom events in the parent window. The detail property in the following code becomes a part of the custom event that is linked with a react component:-
window.addEventListener('react', function(e) {
me.onReactEvent(e.detail, e);
});
class MyLinkCell extends React.Component {
clicked(e) {
const el = e.target;
const eventObj = {
'detail': {
'type': 'downloadlink',
'url': 'react/some/detail/url'
}
};
console.log('clicked - "react" event thrown:');
console.dir(eventObj);
if(window.parent) {
window.parent.dispatchEvent(new CustomEvent('react', eventObj));
}
}
render() {
const {rowIndex, field, data} = this.props;
const link = data[rowIndex][field];
return (
<Cell>
<a onClick={this.clicked} href='#'>{link}</a>
</Cell>
);
}
}
These are the same elements that are used in platforms like Node.js and Angular.js. By importing the JSON package, this can be used to source the relative components on a device.
`watchify index.js --verbose -d -t babelify --sourceMapRelative . --outfile=bundle.js`
Grid Applications and Beyond
Developing React grid applications is much easier and these can be executed on the fly by running the following code to test out the capabilities of the new environment. One can easily see a marked decrease in the code that makes coding elements much simpler and improves the general agile development process.
One great example is the infusion of CSS padding styles with JavaScript buttons that can have as many functions as the application demands. This also helps bring many elements in the web page or application
under a singular head tag.
Ext.define("ExtJSApplication.view.DatePicker", {
id: "componentId",
extend: "Ext.Component",
config: {
reactComp: null
},
afterRender: function () {
this.setReactComp(this.createReactCmp());
},
createReactCmp: function () {
return ReactDOM.render(
React.createElement(ReactLibrary.DatePicker, {
onDateChange: this.onDateChange.bind(this)
}), document.getElementById(this.id)
);
},
onDateChange: function () {
// do something...
}
}
setConfiguration = appName => {
this.getConfiguration(appName).then(module =>
this.setState(
{
appName,
configuration: module.default
},
this.configurationSetCallback
)
);
};
getConfiguration = appName => {
switch (appName) {
case "/automated_actions":
return import(/* webpackChunkName: "automated_actions" */ `../../configurations/automated_actions`);
case "/audit_groups":
return import(/* webpackChunkName: "audit_groups" */ `../../configurations/audit_groups`);
case "/product_manager":
return import(/* webpackChunkName: "product_manager" */ `../../configurations/product_manager`);
case "/mirroring":
return import(/* webpackChunkName: "mirroring" */ `../../configurations/mirroring`);
case "/adgroup_negative_keywords":
return import(/* webpackChunkName: "adgroup_negative_keywords" */ `../../configurations/adgroup_negative_keywords`);
defalt
return import(/* webpackChunkName: "default_configuration" */ `../../configurations`);
}
};
export default new ConfigurationBuilder()
.withGridName("AUTOMATED_ACTIONS")
.withGridDisplayName("Automated Actions")
.withEntityType("automated action")
.withDefaultSort([{ sort: "asc", colId: "S312001" }])
.withGetColumns("/api/flatview/automated_action/columns_extended/")
.withGetData("/api/flatview/automated_action/")
.withColumnsMapping(columnsMapping)
.withLocalizedValue(getLocalizedValue)
.withActionsData(actionsData)
.withDialogs(dialogs)
.build();
How Well Does ReactJS Hold Up
So you’ve got your web applications running on ReactJS and are making transitions speedily by the minute. But what about cross platform development and other applications?
ReactJS employs a host of tools that makes it simpler to employ elements and tags over other packages as well. In the following example of a code snippet for a store that collects data from its users, one can see how cleanly the id tags and functions are interlayered. One of the biggest hassles of a migration scheme is ensuring that everything works the way it used to and shows no changes in functionality or design after migration.
Thanks to the native Javascript architecture, there have been numerous applications of the same in terms of navigation, design, animation and control. While migrations tend to change the syntax and general order of how the code is designed with the mainframe architecture, certain elements, and functionalities remain unchanged even when shifting to ReactJS. The following code might seem familiar to many who’ve worked with ExtJS since the same syntax is used for ReactJS. It’s just cleaner and has a multipurpose touch to it.
import React, { Component } from 'react';
export default class UsersGrid extends Component {
constructor(props) {
super(props);
this.store = Ext.create('Ext.data.Store', {
fields: ['email', 'name'],
data: [
{ "id": 1, "email": "", "name": "" },
{ "id": 2, "email": "landerson1@tripod.com", "name": "Larry Anderson" }, { "id": 3, "email": "gcarroll2@census.gov", "name": "Gerald Carroll" },
{ "id": 4, "email": "asimpson3@patch.com", "name": "Angela Simpson" }, { "id": 5, "email": "dmorales4@digg.com", "name": "Debra Morales" }
] });
} render() {
// create a dom element for the grid's renderTo config
return <div ref="target"/>
}
componentDidMount() {
// once the target is rendered, create and attach a grid
this.grid = Ext.create('Ext.grid.Panel', {
title: 'Users',
height: 500,
width: 800,
renderTo: this.refs.target,
store: this.store,
columns: [
{ text: 'Email', flex: 1, dataIndex: 'email' },
{ text: 'Name', flex: 1, dataIndex: 'name' }
]
});
}
componentWillUnmount() {
// clean up the grid when this component is removed
this.grid.destroy();
}
}
What about HTML applications? Due to ReactJS’s resilient architecture, there are higher chances of combining the applications of a ReactJS framework with a more balanced approach of utility and design. For the nitpicky crowd who happen to know how to dissect a webpage, inspecting the elements in any ReactJS system will reveal code similar to that seen below. Notice how there have been no changes in the structure and syntax of the law even with the transition.
Since ReactJS is lighter than its counterparts, there are lesser chances of breakdowns and other issues. Connecting links and building query blocks also becomes simpler. In short, ReactJs holds up quite smashingly well despite all the commotion it has created in the industry due to the need for migration.
Import React from 'react';
import ReactDOM from 'react-dom';
import UsersGrid from './UsersGrid';
Ext.onReady(function() {
ReactDOM.render(
<UsersGrid/>,
document.getElementById('root')
); });
<x-tabpanel>
<x-panel title="Users" layout="fit">
<x-grid
store={this.store}
columns={[
{ text: 'Email', flex: 1, dataIndex: 'email' },
{ text: 'Name', flex: 1, dataIndex: 'name' }
]} />
</x-panel>
<x-panel title="Something Else">
// various other content here
</x-panel>
</x-tabpanel>
Doubting ReactJS
Some developers might suggest that the best way to look at ReactJS would be as a swiss army knife that can perform multiple functions while being compact and always accessible. For the late entries in the crowd who still seem skeptical about the extension, here are some answers to common queries that pop up when considering its use.
ReactJS differs from native ExtJS components like Angular2, as they lack routing systems. Users would have to rewrite some of the custom components in the target framework as required. On the contrary, however, there is an endless list of choices concerning the number of build tools that can be employed to implement package managers. ReactJS also uses transpilers or polyfills like Babel JS.
Classes are usually defined using an ES6+ class extension that includes React and components for JSX. Unlike Extjs, React classes are not initialized in the setup domain in the same way and have to be added manually. The following code for a scaffolding element reflects this well:-
npm install -g create-react-app
create-react-app my-app
cd my-app/
npm start
sencha app init --ext@6.5.1 --modern MyApp my-app
sencha app watch
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
}
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.App {
text-align: center;
}
.App-logo {
animation: App-logo-spin infinite 20s linear;
height: 80px;
}
.App-header {
background-color: #222;
height: 150px;
padding: 20px;
color: white;
}
.App-intro {
font-size: large;
}
@keyframes App-logo-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
Fetching References and Other Issues
Fetching references using Extjs would require restructuring the tag elements in the CSS sheets and then making changes in the Javascript section. With Ext JS, there are plenty of ways to fetch a reference to a particular component. There are, however, subtle differences that cannot be missed with respect to ExtJS. Users would find the referencing system in ReactJS more declarative.
Let’s move on to component properties. Say for example, that there was a list or tab with a border, padding or margin that has to be adjusted to another colour. These changes can be manifested easily as React components have properties that are set on the element itself. But what if a user happens to change them at runtime? Making those changes at runtime would only result in the component being replaced once again in the browser. However, the number of steps that the system would go through to get a declarative change in the component property is often too long and requires additional coding.
A more natural alternative is to define a global variable or a state object that passes down the properties of the component to its props. Since ReactJS only supplies the views, users can install a state management solution such as Redux or Mobx. The React community has also eased the process of code sharing by focusing entirely on GitHub functionality that allows users to push and pull code on the go.
Sharing component apps and more significant elements may seem riskier due to the complexity of JSON files on the internet, but initial users have stated that such problems seem rare. However, there may be problems when fetching data from remote sources with the .json file extension. App builders and coders who work with massive amounts of datasets may find it tedious to load every dataset from the same terminal window. Fortunately, ReactJS libraries support multi-table views and also have reasonable extensions for performing operations on relational database management systems.
Users can use the loadRecord() method to import data files straight to tables that can be styled according to CSS elements. This also makes way for simple dragging and dropping, given that the website supports it.
An important question that comes up is whether React has any library-specific events. While the main shell client doesn’t allow any such functionalities, users can use DOM events and install custom events in the components. The activities can be further coded to style the React app with library components and elements.
Games can be modified into the template system supported by HTML. React is equipped with server-side rendering (SSR) solutions such as renderToString and renderToNodeStream (react-dom package) which are perfect for apps that have multiple panes and require quick load out times.
An Edge Above ExtJS
One can see the capabilities of having Extjs components migrated to the ReactJS platform and the advantages that it offers. As a closing remark, remember that a total migration might not be the best option, especially when employees and IT personnel are working on the mainframe.
Check out the localStorage libraries from ReactJS to know more about how the data and code can be stored without tampering with any existing processes. Creating a network map of the various elements along with the subclasses, plugins and mixins is highly suggested to avoid confusions. Always start the migration process from the smallest components and move on to the broader domains.
If you transfer to a new ReactJS codebase, work on the MVP features that will define the unique elements that are imported. There is, however, a disadvantage to how Ext JS has components implemented for every button, label, list, checkbox and textbox. The user may be left overwhelmed by the sheer magnitude of junk code that offers no use. But such an extensive system can be fixed using some indenting and code editing.
Further Reading
Published at DZone with permission of Shital Agarwal. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments