Building e-Business 7.0 Controls Using React

This document provides the guidelines for building an e-Business control using React and consists of below sub-topics.

Refer to Guidelines for building or extending e-Business 6.0 Controls for controls built using Knockout .js

Prerequisite Knowledge

Key changes in the e-Business 7.0 Frontend implementation

  • A new jsx folder is created to store the JavaScript XML (JSX) files for the new controls.

  • Developers will be able to write their React code in JSX (easier than writing in JavaScript). However, as JSX is not supported in most browsers, they need to be transpiled to JS.

  • Post transpilation of the JSX files, their corresponding JS files are automatically created in the js folder.

  • For controls built using React, the HTML landing page files references the transpiled JS file and not the manually coded JSX file.

  • The landing page HTML file should not contain any JS code, for example, for the initial service calls, for the knockout bindings' etcetera. It must only contain the references to all of the JS, CSS and JSX files along with the “div” elements with ID attributes, for loading controls on the html page.

  • The initial service calls and Knockout bindings must now be included in the JSX files.

  • Two new files, react.production.min.js and react-dom.production.min.js, are added into the js/3rdParty folder. These will be referenced in the HTML landing page files for using React in our controls.

  • The HTML template file for a control under the html folder is no longer needed as the HTML for the control’s body is written in the JSX file.

Getting Started

  1. Installation of Node.js and npm (Node Package Manager)

    1. React development requires Node.js to be installed on your environment. It can be downloaded from the following link: - https://nodejs.org/en/download/

    2. npm comes bundled with the Node.js installable after v0.6.3 version. To verify the same, open command prompt and type the following command and see the result: npm --version

  2. Installation of React, React DOM, babel-cli, babel-preset-react and babel-plugin-transform-react-jsx

    1. The front-end project in the e-Business 7.0 setup includes the package.json file that contains a list of dependencies for React development.

    2. Open the Command Prompt and switch to the directory that holds the e-Business front-end project.

    3. Run the following command to install all necessary dependencies mentioned in the package.json file: npm install

    4. Alternatively, run the following commands to manually install all dependencies.

      1. Create package.json file: npm init -y

      2. Install react and react-dom : npm install react react-dom --save

      3. Install Babel : npm install babel-cli babel-preset-react babel-plugin-transform-react-jsx

Control level guidelines with examples.

  • While developing a control, create one Landing page HTML file and one JSX file with the same name.
    For example: committees/CommitteeListing.html and jsx/committees/CommitteeListing.jsx

  • The HTML landing page files must contain the references to all of the JS, CSS and JSX files along with the “div” elements with ID attributes, for loading controls on the html page.

  • One of these “div” elements is where the current control’s HTML will be rendered. Make sure to name it as per the control’s name, for example, for CommitteeListing control, the div would have ID, committeeListing, as shown below:

<div class="ebBody ebWrapper">
    <div id="committeeListing"></div>
</div>
  • Make sure to add references to the react.production.min.js and react-dom.production.min.js files which are required to use React in our code, as shown below:

    <script src="js/3rdParty/react.production.min.js"></script>
    <script src="js/3rdParty/react-dom.production.min.js"></script>
  • Just before the closing </body> tag, add a reference to the JS file which is created automatically after transpiling its corresponding JSX file, as shown below:

    <!-- Load our React component. -->
    <script src="../js/committees/CommitteeListing.js"></script>
  • In the JSX file, a variable has to be created that will act as a collection for all of the control's objects. 
    For example: var eb_CommitteeListing = eb_CommitteeListing || {};

  • The control objects can be SitePath, TemplatePath, ServicePath, service URLs and control specific properties.

  • Once the control objects have been defined, import the useState and useEffect hooks like below:

const { useState, useEffect } = React;

  • The data for the control has to be managed in the form of state. In order to do this, we use the useState hook, as shown below:

const [committeeList, setCommitteeList] = useState(null);

  • In order to perform actions based on certain conditions, use the useEffect hook,

useEffect(() => {
  .................
  Action to perform
  .................
  }, [optionalState]);
  • The controls have to be developed as functional components in the following manner:

const ControlName = () => {
    ........
    ........
    ........
    
    return (
      ..HTML..
      ..Code..
    );
};

React requires that the name of the component is in PascalCase, that is, the first letter of each word needs to be capitalized to avoid errors.

  • The first section of the code to be included in the functional component is the useEffect hook, which executes on page load. This block of code must contain the initial service calls and knockout bindings of pre-existing controls (such as, header menu and shopping cart)

useEffect(() => {
        eb_UserContext.getContextData(true).done(function (userData) {
            eb_UserContext.live = new eb_UserContext.model(userData);
            if (eb_UserContext.live.isUserLoggedIn()) {
                eb_shoppingCart.getShoppingCart(eb_UserContext.live.LinkId()).done(function (cartData) {

                    var cartOptions = {};
                    cartOptions.shoppingCartData = cartData;
                    eb_shoppingCart.live = new eb_shoppingCart.shoppingCartModel(cartOptions);

                    //load footer control
                    var footerOptions = footerOptions || {};
                    footerOptions.domElement = eBusinessJQObject('#ebFooter')[0];
                    footerOptions.templatePath = eb_Config.SitePath + "html/Footer.html";
                    eb_Footer.render(footerOptions).done(function () {
                        //load header control
                        var headerOptions = headerOptions || {};
                        headerOptions.domElement = eBusinessJQObject('#ebHeaderMenu')[0];
                        headerOptions.templatePath = eb_Config.SitePath + "html/HeaderMenu.html";
                        headerOptions.userContext = eb_UserContext.live;
                        headerOptions.shoppingCart = eb_shoppingCart.live;
                        headerOptions.activePage = "committeeListing";
                        headerOptions.sitePath = "../";
                        eb_HeaderMenu.render(headerOptions).done(function () {
                            eb_HeaderMenu.live = new eb_HeaderMenu.model(headerOptions);
                            ko.applyBindings(eb_HeaderMenu.live, headerOptions.domElement);/*Apply KO bindings, fire up the control*/

                            /*Fetch call to retrieve list of committees.*/
                            fetch(eb_committeeListing.getCommitteeListService, {
                                method: 'get',
                                credentials: 'include'
                            })
                                .then(response => {
                                    if (!response.ok) {
                                        throw Error(eb_committeeListing.defaultErrorMessage);
                                    }
                                    return response.json();
                                })
                                .then(data => {
                                    setCommitteeList(data);
                                    setCommitteeListToShow(data);
                                    setIsLoading(false);
                                    setError(null);
                                })
                                .catch(err => {
                                    setIsLoading(false);
                                    setError(err.message);
                                })

                        }).fail(function (data, msg, jhr) {
                            console.error('Failed to render header control...');
                            eb_Config.getErrorMessageForControl(data.responseJSON, eb_committeeListing);
                        });
                    }).fail(function (data, msg, jhr) {
                        console.error('Failed to render footer control...');
                    });
                }).fail(function (data, msg, jhr) {
                    console.error('Failed to getShoppingCart...');
                    eb_Config.getErrorMessageForControl(data.responseJSON, eb_committeeListing);
                });
            }else {
                (window.location.assign(eb_Config.loginPageURL));
            }
        }).fail(function (data, msg, jhr) {
            console.error("Failed to get user context data.");
        });

    }, []);
  • The functional component needs to have a return statement which contains the HTML of the actual control’s content. JSX comes in handy while writing HTML along with React states mentioned in the control code above. Make sure to enclose the HTML under a div named after the current control. For example,

return (
        <div className="committeeListing">
            ....................
            HTML code
            ....................
        </div>
);
  • This newly created functional component needs to be rendered onto the div element which is mentioned on the Landing page HTML file like so,

const root = ReactDOM.createRoot(document.getElementById('committeeListing'));
root.render(<CommitteeListing />);
  • In order to make calls to the services used by the React components, use the FETCH API like below:

fetch(eb_committeeListing.getCommitteeListService, {
                                method: 'get',
                                credentials: 'include'
                            })
                                .then(response => {
                                    if (!response.ok) {
                                        throw Error(eb_committeeListing.defaultErrorMessage);
                                    }
                                    return response.json();
                                })
                                .then(data => {
                                    setCommitteeList(data);
                                    setCommitteeListToShow(data);
                                    setIsLoading(false);
                                    setError(null);
                                })
                                .catch(err => {
                                    setIsLoading(false);
                                    setError(err.message);
                                })

Post JSX development

Once the development of the control has been done in JSX, follow the steps below to transpile the JSX file into JS:

  1. Open Command prompt and navigate to the directory that holds the e-Business front-end project.

  2. Run the following command.

C:\LatestReact>node_modules\.bin\babel --plugins transform-react-jsx jsx_directory_path -d js_directory_path

For example,

C:\LatestReact>node_modules\.bin\babel --plugins transform-react-jsx jsx/committees -d js/committees.

jsx/committees, is the directory that holds all the developed JSX files for the committees' feature.

js/committees, is the directory where the newly created JS files are placed automatically post JSX transpiling.

 

Was this article helpful?
0 out of 0 found this helpful

Comments

0 comments

Please sign in to leave a comment.