Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / React

From jQuery to React: the Transition of Thinking in Front-end Development

4.00/5 (8 votes)
25 Sep 2017CPOL7 min read 18.5K  
Functional programming in front-end development

Introduction

Web front-end has been exciting these years: new frameworks and tools appear each year. Today, there are three major front-end frameworks: Angular, React, and Vue, and the most popular one is probably React. React stands for the current thinking and trend for front-end development: web components. Also, this is part of the current web development architecture: front-end and back-end separation. For traditional back-end MVC frameworks (like the numerous PHP ones), the View part in these frameworks is not important anymore (do you remember those ‘template engines’?). Back-end becomes Restful APIs or microservices today (the Controllers and Models are still there, and the output is just JSON data fed to front-end and mobile apps).

React

We have been using jQuery for front-end with back-end MVC frameworks for so many years, it is still convenient and great, but in today’s front-end and back-end separation architecture, it is not suitable here anymore. It’s time to switch to React.

React is not just a JavaScript library, it is a whole tech stack (we need to use Babel to transpile ES2015; need to use Webpack to bundle, or pack up, modules; need to use Gulp for automated tasks, etc.). More importantly, React and Redux (and its middleware) stand for a different programming methodology - Functional Programming in front-end applications.

React separates a web page into various components, each component encapsulates:

  • Presentation: HTML/JSX
  • Style: CSS
  • Behavior: JavaScript

And each component can be reusable. All the components together form an app. It sounds very different from what MVC has been promoting for more than a decade: to separate code from HTML. Let’s first create a React component to see what it looks like. If you do not have a React project scaffolding at hand, you can use Facebook’s Create React App tool:

It’s very easy to use, just to run:

npm install --global create-react-ap

to install this npm package globally. You can also use Yarn (https://yarnpkg.com/en/), another newer NodeJS package manager. Then, you can use this command to create a React project:

create-react-app react-test

and then enter the project directory:

cd react-test/

Now if you take a look at the content of the package.json file:

JavaScript
{
// .....
"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test --env=jsdom",
  "eject": "react-scripts eject"
}
}

there is a “start” command in the “scripts” member. To start the app, run:

npm start

or:

npm run start

(The full command is actually “npm run + xxx”, but for the start command, it can be shortened to just “npm start”). Then in your browser (highly recommend Chrome for React, so far the best), open http://localhost:3000/ to see the app we just created.

You can open the project using your favorite editor or IDE (recommend VS Code for editor or WebStorm/PHPStorm for IDE). The entry file for the project is ./src/index.js.

React
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

registerServiceWorker();

The page in the browser you just saw is from this component:

JavaScript
import App from './App';

In this component, it also contains its CSS file:

JavaScript
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';  // Import CSS file for this App component

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>
  );
}
}

export default App;

So this App component encapsulates CSS, but it has no JavaScript code there, let’s add one button and assign an event handler to it:

JavaScript
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';  // Import CSS file for this App component

// Add css style for the new button

const buttonStyle = {
  margin: '10px',
  width: '150px',
  backgroundColor: '#F58423',
  borderRadius: '3px'
};

class App extends Component {
  onButtonClick() {
    alert("Clicked the button!");
}

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>
          <button style={buttonStyle} onClick={this.onButtonClick.bind(this)}>Click Me</button>
      </div>
    </div>
  );
}
}

export default App;

Notice the CSS attribute “background-color” needs to be changed to backgroundColor in JSX. Why? The reason is all JSX is actually running under JavaScript runtime, they are in fact JavaScript code, and “background-color” is just not a valid variable name in JavaScript.

Now we need an event handler for the button. In React, we can use onClick to add an event handler function to an element, but this onClick is totally different from HTML’s onclick attribute. Many years ago, developers started to avoid embedding onclick in HTML, because this will mess up the code. Instead, we have been using jQuery’s way to add event handler function. We would do like this:

HTML
<div>
    <button id="testButton">Click Me</button>
</div>

in HTML, we have an id attribute for the button element, then in <script> tag, we will use jQuery:

HTML
<script src="./jquery.min.js"></script>
<script>
      $(document).ready(function () {
          $('#testButton').click(function () {
              alert("Clicked the button!");
          });
      });
</script>

jQuery’s way is to:

  1. Get the button element using CSS rules
  2. Append an anonymous callback function as the event handler
  3. In the event callback function, do the things needed for this onclick event. For example, to select other DOM elements on the page, and modify/hide/show them

This programming pattern - “when an event occurs, in the callback function, select DOM element to modify or to show/hide it”, is the simplest way and it’s very easy to understand. That’s how jQuery was invented at that time.

Are React and JSX going back? No, React is doing things a different way. When we add the onclick event handler in HTML, this onclick event handler function is executed under global scope, which could cause “global variable contamination”. Also adding many event handler functions to the DOM elements could affect page’s performance, especially when there are a great number of them.

But React has no such problems. When we use onClick in JSX, it is not converted HTML’s onclick. React uses “event delegation” to handle events, so no matter how many onClicks we use in JSX, eventually there will just be one event handler function hung on the top of DOM tree. All click events are just captured by this chief event handler function, and then get assigned to a specific function to process.

Also, React has many component life cycle functions, such as:

  • componentWillMount()
  • componentDidMount()
  • shouldComponentUpdate()
  • componentWillUpdate()
  • componentDidUpdate()

They are just “hooker functions”. Thanks to these life cycle functions, when a component is unmounted, all the event handler functions for this component will be released. By the way, the naming conversion of these life cycle functions are borrowed from iOS, e.g.:

  • loadView()
  • viewDidLoad()
  • viewWillAppear()
  • viewDidAppear()

Also React brings with Virtual DOM and its Diff algorithm, because directly manipulating DOM nodes are slowing down page’s performance. Even just one DOM manipulation will cause the browser to layout and render the page again, which is much slower than executing a JavaScript statement. Different from jQuery, React is data-driven: an event triggers data(state) change, then data(state) change triggers render; during rendering, Virtual DOM will compare against last time’s Virtual DOM and spot the differences. Then when to modify the actual DOM tree, it only needs to take care of the changed parts.

From the example above, you can see that traditionally CSS is in .css files, JavaScript is in .js files, and HTML is in .html or template files. React puts these three all in one .js or .jsx file, as the purpose of these three is to work together to implement one functionality. This way shows the discipline of High Cohesion. Today, more and more developers realized back-end’s MVC style might not suit best for front-end, and React (and Redux) brings functional reactive programming into the front-end just in time.

There are some important characters in functional programming:

  1. Function is the first-class citizen. This is true in JavaScript. One feature many imperative programming languages lack but JavaScript has is to declare one function inside another function. Also, JavaScript function is an object and it can be passed as parameters. Plus, one function's result can also be a function.
  2. Data is immutable. In “pure” functional programming, data is not changeable, so there are no ‘variables’. All the data cannot be changed, and if it needs to be changed, the only way is to produce new data.
    This philosophy is well embodied in React and Redux:
    • In React, it emphasis that one component should not change the passed-in props;
    • In Redux, one reducer function cannot modify the store’s state, but just generates a new one, often use ES2015’s Object.assign() method.
  3. Use pure function. A pure function is just like a function in math, which has no side effects, meaning the output of the function is only determined by the input.

In React, each component’s render() function is a pure function. It means the result of the rendering is only determined by the component’s state and props. A formula for React is:

JavaScript
UI = f(state)

In Redux, each reducer must also be a pure function.

 

Although many projects are still using jQuery, React and Redux brings spring to the front-end area. This transition is not about a new language/library, but a tech stack and a programming paradigm.

P.S. There is a good article called “Thinking in React” by Facebook that is worth reading:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)