While training people on React, I came to the conclusion that React is all about JavaScript. Also, a lot of the material is about JavaScript rather than React. Most of these are JavaScript ES6 and its features and syntax, but also include ternary operators, simplified syntax, this objects, JavaScript built-in functions (Map, Reduce, filter), or more general concepts such as composability, reusability, immutability, or higher-order functions. You may not need to know the basics of React before you start, but you’ll definitely need to use them as you learn or practice. This article lists most useful JavaScript features that will give you a leg up as you learn React.

When you begin to enter the React of the world, create the React – app (https://github.com/facebook/create-react-app) is usually your first React project. After setting up your project, you should see the React class component below:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    );
  }
}

export default App;Copy the code

A React class component might not be the best place to start. Newcomers have a lot to digest that doesn’t necessarily have to do with React: class statements, class methods, and inheritance. Import statements also add additional complexity when learning React. While the main focus should be on JSX (React syntax), there are other things that need explaining as well. This article focuses on JavaScript, so don’t worry too much about React.

The React class component requires prior knowledge of JavaScript classes. The concept of JavaScript classes is relatively new. Previously, only JavaScript prototype chains were available to implement inheritance. JavaScript classes are based on archetypal inheritance to make inheritance systems simpler.

One way to define the React component is to use JavaScript classes.

class Developer {
  constructor(firstname, lastname) {
    this.firstname = firstname;
    this.lastname = lastname;
  }

  getName() {
    return this.firstname + ' ' + this.lastname;
  }
}

var me = new Developer('Robin', 'Wieruch');

console.log(me.getName());Copy the code

A class describes an entity and is used to create instances of that entity. When an instance of a class is created using the new statement, the constructor of that class is called. The attributes of a class are usually located in the constructor. In addition, class methods (such as getName()) are used to read (or write) the instance’s data. Instances of the class are represented in the class using the This object, but externally only specified to JavaScript variables.

In object-oriented programming, classes are often used to implement inheritance. In JavaScript, too, the extends statement can be used to make one class inherit from another. A subclass inherits all the functionality of a parent class through the extends statement and can add functionality of its own.

class Developer {
  constructor(firstname, lastname) {
    this.firstname = firstname;
    this.lastname = lastname;
  }

  getName() {
    return this.firstname + ' ' + this.lastname;
  }
}

class ReactDeveloper extends Developer {
  getJob() {
    return 'React Developer';
  }
}

var me = new ReactDeveloper('Robin', 'Wieruch');

console.log(me.getName());
console.log(me.getJob());Copy the code

Basically, that’s all you need to know to understand the React class component. The JavaScript class defines the React Component, which inherits all the functionality of the React Component class imported from the React package.

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
        <h1>Welcome to React</h1>
      </div>
    );
  }
}

export default App;Copy the code

That’s why the Render () method is required in the React class Component: the React Component imported from the React package uses it to display something in the browser. In addition, other lifecycle methods (including the Render () method) cannot be used if you do not inherit from the React Component. For example, without inheritance, the componentDidMount() lifecycle method doesn’t exist, because now the class is just an instance of a normal JavaScript class. In addition to the lifecycle methods not available, React API methods (such as this.setstate () for local state management) are also not available.

We can extend the behavior of generic classes through JavaScript classes. Therefore, we can introduce our own class methods or attributes.

import React, { Component } from 'react';

class App extends Component {
  getGreeting() {
    return 'Welcome to React';
  }

  render() {
    return (
      <div>
        <h1>{this.getGreeting()}</h1>
      </div>
    );
  }
}

export default App;Copy the code

Now you should know why React uses JavaScript classes to define React class components. Use them when you need to access the React apis (lifecycle methods, this.state, and this.setState()). Next, you’ll see how to define React components in different ways, such as not using JavaScript classes, because sometimes you may not need to use class methods, lifecycle methods, or states.

Although we can use JavaScript class inheritance in React, this is not a desirable outcome for React because React favors composition over inheritance. Therefore, the only class your React Component needs to extend should be the React Component.

When I train people on React, I start by explaining JavaScript arrow functions to them. The arrow function is one of the new language features in ES6 that brings JavaScript one step closer to functional programming.

// JavaScript ES5 function
function getGreeting() {
  return 'Welcome to JavaScript';
}

// JavaScript ES6 arrow function with body
const getGreeting = () => {
  return 'Welcome to JavaScript';
}

// JavaScript ES6 arrow function without body and implicit return
const getGreeting = () =>
  'Welcome to JavaScript';Copy the code

JavaScript arrow functions are often used in React applications to keep the code concise and readable. I’m a big fan of arrow functions and always try to remake my functions from JavaScript ES5 to ES6. I use the arrow function of JavaScript ES6 at some point when the difference between JavaScript ES5 functions and JavaScript ES6 functions is obvious. However, for newcomers to React, the many different syntax can be overwhelming. So, BEFORE using them in React, I’ll try to explain the different features of JavaScript functions. In the following sections, you’ll learn how to use JavaScript arrow functions in React.

React uses a different programming paradigm, thanks to the fact that JavaScript is a generalist programming language. For object-oriented programming, the React class component makes good use of JavaScript classes (the React component API’s inheritance, class methods, and class properties, such as this.state). React (and its ecosystem), on the other hand, also uses a lot of functional programming concepts. For example, the React function stateless component is another way to define a React component. So what if you could use components like functions?

function (props) {
  return view;
}Copy the code

This is a function that takes input (such as props) and returns an HTML element (view). It does not need to manage any state (stateless), nor does it need to understand any methods (class methods, lifecycle methods). This function only needs to render using the Render () method of the React component.

function Greeting(props) {
  return <h1>{props.greeting}</h1>;
}Copy the code

Feature stateless components are the preferred way to define components in React. They have less boilerplate code, lower complexity, and are easier to maintain than React class components. Both, however, have their own reasons for being.

Having mentioned JavaScript arrow functions and their ability to improve code readability, let’s apply these functions to stateless components. The previous Greeting component is written a little differently in JavaScript ES5 and ES6:

// JavaScript ES5 function
function Greeting(props) {
  return <h1>{props.greeting}</h1>;
}

// JavaScript ES6 arrow function
const Greeting = (props) => {
  return <h1>{props.greeting}</h1>;
}

// JavaScript ES6 arrow function without body and implicit return
const Greeting = (props) =>
  <h1>{props.greeting}</h1>Copy the code

The JavaScript arrow function is a great way to keep the React stateless component simple.

React has evolved in the way it defines components. In the early stages, the React.createclass () method was the default way to create a React class component. This method is no longer used because with the rise of JavaScript ES6, the previous React class component syntax became the default.

But JavaScript is also evolving, so JavaScript enthusiasts are always looking for new ways to do it. That’s why you’ll notice that the React class component uses a different syntax. One way to define React class components using state and class methods is as follows:

class Counter extends Component { constructor(props) { super(props); this.state = { counter: 0, }; this.onIncrement = this.onIncrement.bind(this); this.onDecrement = this.onDecrement.bind(this); } onIncrement() { this.setState(state => ({ counter: state.counter + 1 })); } onDecrement() { this.setState(state => ({ counter: state.counter - 1 })); } render() { return ( <div> <p>{this.state.counter}</p> <button onClick={this.onIncrement} type="button">Increment</button> <button onClick={this.onDecrement} type="button">Decrement</button> </div> ); }}Copy the code

However, when implementing a large number of React class components, the class-method bindings and constructors in the constructors themselves become cumbersome implementation details. Fortunately, there’s a short syntax for getting rid of both of these annoyances:

class Counter extends Component { state = { counter: 0, }; onIncrement = () => { this.setState(state => ({ counter: state.counter + 1 })); } onDecrement = () => { this.setState(state => ({ counter: state.counter - 1 })); } render() { return ( <div> <p>{this.state.counter}</p> <button onClick={this.onIncrement} type="button">Increment</button> <button onClick={this.onDecrement} type="button">Decrement</button> </div> ); }}Copy the code

By using JavaScript arrow functions, class methods can be automatically bound, without binding them in the constructor. By defining the state directly as a class attribute, you can omit the constructor when you don’t use props. (Note: Please note that JavaScript does not yet support class attributes.) So you could say that this way of defining React class components is cleaner than the other versions.

Template literals are another JavaScript language feature that comes with JavaScript ES6. This feature is mentioned because it can be confusing for newcomers to JavaScript and React when they see it. Take the syntax for the following connection string:

function getGreeting(what) {
  return 'Welcome to ' + what;
}

const greeting = getGreeting('JavaScript');
console.log(greeting);
// Welcome to JavaScriptCopy the code

Template literals can be used for the same purpose, called string interpolation:

function getGreeting(what) {
  return `Welcome to ${what}`;
}Copy the code

You simply insert JavaScript primitives using backquotes and ${}. String literals can be used not only for string interpolation, but also for multi-line strings:

function getGreeting(what) {
  return `
    Welcome
    to
    ${what}
  `;
}Copy the code

This allows you to format multi-line blocks of text.

When teaching JSX syntax to React novices, I usually define a variable in the Render () method and then use it in the return code block.

import React, { Component } from 'react';

class App extends Component {
  render() {
    var greeting = 'Welcome to React';
    return (
      <div>
        <h1>{greeting}</h1>
      </div>
    );
  }
}

export default App;Copy the code

You only need to use curly braces to manipulate JavaScript in HTML. Whether you render a string or a complex object, there’s not much difference.

import React, { Component } from 'react';

class App extends Component {
  render() {
    var user = { name: 'Robin' };
    return (
      <div>
        <h1>{user.name}</h1>
      </div>
    );
  }
}

export default App;Copy the code

The next question is: How do I render the list of items? React does not provide specific apis (such as custom attributes for HTML tags) for rendering lists of items. We can use pure JavaScript code to iterate over the list of items and return the HTML for each item.

import React, { Component } from 'react';

class App extends Component {
  render() {
    var users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    return (
      <ul>
        {users.map(function (user) {
          return <li>{user.name}</li>;
        })}
      </ul>
    );
  }
}

export default App;Copy the code

By using JavaScript arrow functions, you can get rid of the arrow function body and return statements, making the render output more concise.

import React, { Component } from 'react';

class App extends Component {
  render() {
    var users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    return (
      <ul>
        {users.map(user => <li>{user.name}</li>)}
      </ul>
    );
  }
}

export default App;Copy the code

Soon, every React developer became accustomed to JavaScript’s built-in map() method. It is useful to map an array and return render output for each item. In some cases, it is more useful to use a combination of filter() and reduce() instead of just rendering output for each item that is mapped.

import React, { Component } from 'react';

class App extends Component {
  render() {
    var users = [
      { name: 'Robin', isDeveloper: true },
      { name: 'Markus', isDeveloper: false },
    ];

    return (
      <ul>
        {users
          .filter(user => user.isDeveloper)
          .map(user => <li>{user.name}</li>)
        }
      </ul>
    );
  }
}

export default App;Copy the code

In general, React developers are used to using JavaScript’s built-in functions without having to use the React specific API. It’s just JavaScript in HTML.

Declaring variables using var, let, and const may also be confusing for newcomers to React, even though they are not React related. I’ll try to introduce let and const early in the tutorial, starting by using const and var interchangeably in the React component:

import React, { Component } from 'react';

class App extends Component {
  render() {
    const users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    return (
      <ul>
        {users.map(user => <li>{user.name}</li>)}
      </ul>
    );
  }
}

export default App;Copy the code

I then gave some rules of thumb for using these variable declarations:

(1) Don’t use var because let and const are more specific

(2) Const is used by default because it cannot be reassigned or redeclared

(3) If a variable is to be reassigned, let is used

Let is usually used in a for loop, and const is usually used to keep JavaScript variables unchanged. Although you can modify the internal properties of objects and arrays when using const, variable declarations express the intent to leave variables unchanged.

What if I want to conditionally render with an if-else statement? We cannot use if-else statements directly in JSX, but we can return them early from the render function. It is legal in React to return NULL if the content is not displayed.

import React, { Component } from 'react'; class App extends Component { render() { const users = [ { name: 'Robin' }, { name: 'Markus' }, ]; const showUsers = false; if (! showUsers) { return null; } return ( <ul> {users.map(user => <li>{user.name}</li>)} </ul> ); } } export default App;Copy the code

However, if you want to use if-else statements in the returned JSX, you can use JavaScript’s ternary operators:

import React, { Component } from 'react';

class App extends Component {
  render() {
    const users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    const showUsers = false;

    return (
      <div>
        {
          showUsers ? (
            <ul>
              {users.map(user => <li>{user.name}</li>)}
            </ul>
          ) : (
            null
          )
        }
      </div>
    );
  }
}

export default App;Copy the code

If you return only one aspect of a conditional rendering, use the && operator:

import React, { Component } from 'react';

class App extends Component {
  render() {
    const users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    const showUsers = false;

    return (
      <div>
        {
          showUsers && (
            <ul>
              {users.map(user => <li>{user.name}</li>)}
            </ul>
          )
        }
      </div>
    );
  }
}

export default App;Copy the code

Detailed principle I will not say, but if you are interested, you can in this article (https://www.robinwieruch.de/conditional-rendering-react/) to know more detailed information and other technical conditions for rendering related. Conditional rendering in React tells us that most React is JavaScript related, not React specific.

In JavaScript, we can import and export functionality defined in JavaScript ES6 files through import and export statements.

These import and export statements are another topic to learn about before starting your first React application. The create-react-app project already uses import statements:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    );
  }
}

export default App;Copy the code

This is great for initial projects because it gives you a full experience of importing and exporting other files. However, I tried to avoid these imports when I first got into React. Instead, I’ll focus on the JSX and React components. Import and export statements need to be introduced only when the React component or JavaScript functions need to be separated into separate files.

How about using these import and export statements? Suppose you want to export the following variables of a file:

const firstname = 'Robin'; const lastname = 'Wieruch'; export { firstname, lastname }; You can then import them into another file using the relative path of the first file: import {firstName, lastName} from './file1.js'; console.log(firstname); // output: RobinCopy the code

So it doesn’t have to be just about importing or exporting components or functions, it can be about sharing everything that can be assigned to variables (we’re just talking ABOUT JS). You can also import all variables exported from another file as an object:

import * as person from './file1.js'; console.log(person.firstname); // output: Robin Imports can have aliases. Aliases are needed when importing functionality with the same export name from multiple files. import { firstname as username } from './file1.js'; console.log(username); // output: RobinCopy the code

All of the previous examples were named imports and exports. In addition, there are default imports and exports. It can be used in the following scenarios:

  • Export and import individual functions;

  • Highlight the main functions of a module’s export API;

  • As a backup for the import function.

const robin = { firstname: 'Robin', lastname: 'Wieruch', }; export default robin; You can omit the braces when using the default import: import developer from './file1.js'; console.log(developer); // output: { firstname: 'Robin', lastname: 'Wieruch' }Copy the code

In addition, the import name can be different from the default name of the export. You can also use it with named export and import statements:

const firstname = 'Robin';
const lastname = 'Wieruch';

const person = {
  firstname,
  lastname,
};

export {
  firstname,
  lastname,
};

export default person;Copy the code

Import in another file:

import developer, { firstname, lastname } from './file1.js';

console.log(developer);
// output: { firstname: 'Robin', lastname: 'Wieruch' }
console.log(firstname, lastname);
// output: Robin WieruchCopy the code

You can also save a few lines by exporting the named variable directly:

export const firstname = 'Robin';
export const lastname = 'Wieruch';Copy the code

These are the main functions of the ES6 module. They can help you better organize your code and design reusable module apis.

React is just the view layer of the application. React provides some internal state management, but beyond that, it’s just a library of components that render HTML for the browser. Apis (such as browser apis, DOM apis), JavaScript, or external libraries can add extra things to React. Choosing the right library for your React application isn’t always easy, but once you have a good understanding of the different libraries, you can choose the one that best fits your technology stack.

For example, we can use React’s native fetch API to fetch data:

import React, { Component } from 'react'; class App extends Component { state = { data: null, }; componentDidMount() { fetch('https://api.mydomain.com') .then(response => response.json()) .then(data => this.setState({  data })); } render() { ... } } export default App;Copy the code

But you can also use another library to get the data, and Axios is a popular one:

import React, { Component } from 'react';
import axios from 'axios';

class App extends Component {
  state = {
    data: null,
  };

  componentDidMount() {
    axios.get('https://api.mydomain.com')
      .then(data => this.setState({ data }));
  }

  render() {
    ...
  }
}

export default App;Copy the code

So once you know what problems you need to solve, the React ecosystem provides you with plenty of solutions. This may not be about React per se, but rather about knowing how to choose the various JavaScript libraries that can be used to complement the React application.

Higher-order functions are a great concept in functional programming. In React, it makes sense to know these functions, because at some point you’ll need to deal with higher-order components, and if you already know higher-order functions, you’ll know them better.

We assume that the list of users can be filtered based on the value of an input field.

import React, { Component } from 'react';

class App extends Component {
  state = {
    query: '',
  };

  onChange = event => {
    this.setState({ query: event.target.value });
  }

  render() {
    const users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    return (
      <div>
        <ul>
          {users
            .filter(user => this.state.query === user.name)
            .map(user => <li>{user.name}</li>)
          }
        </ul>

        <input
          type="text"
          onChange={this.onChange}
        />
      </div>
    );
  }
}

export default App;Copy the code

We don’t always want to do this by extracting functions, as this can add unnecessary complexity. However, by extracting the function, we can test it separately. So let’s use the built-in filter function to implement this example.

import React, { Component } from 'react';

function doFilter(user) {
  return query === user.name;
}

class App extends Component {
  ...

  render() {
    const users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    return (
      <div>
        <ul>
          {users
            .filter(doFilter)
            .map(user => <li>{user.name}</li>)
          }
        </ul>

        <input
          type="text"
          onChange={this.onChange}
        />
      </div>
    );
  }
}

export default App;Copy the code

This implementation doesn’t work yet, because the doFilter() function needs to know the Query attribute of state. We can pass it through another wrapper function, the higher-order function.

import React, { Component } from 'react';

function doFilter(query) {
  return function (user) {
    return query === user.name;
  }
}

class App extends Component {
  ...

  render() {
    const users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    return (
      <div>
        <ul>
          {users
            .filter(doFilter(this.state.query))
            .map(user => <li>{user.name}</li>)
          }
        </ul>

        <input
          type="text"
          onChange={this.onChange}
        />
      </div>
    );
  }
}

export default App;Copy the code

Basically, higher-order functions are functions that return functions. By using JavaScript ES6’s arrow functions, you can make higher-order functions more concise. In addition, this simplified approach makes composing functions into functions more attractive.

const doFilter = query => user =>
  query === user.name;Copy the code

The doFilter() function can now be exported from the file and tested separately as a pure (higher-order) function. Now that you know the higher-order functions, you’re ready to learn the higher-order components of React.

Extracting these functions into (higher-order) functions outside the React component also helps test React’s local state management separately.

export const doIncrement = state => ({ counter: state.counter + 1 }); export const doDecrement = state => ({ counter: state.counter - 1 }); class Counter extends Component { state = { counter: 0, }; onIncrement = () => { this.setState(doIncrement); } onDecrement = () => { this.setState(doDecrement); } render() { return ( <div> <p>{this.state.counter}</p> <button onClick={this.onIncrement} type="button">Increment</button> <button onClick={this.onDecrement} type="button">Decrement</button> </div> ); }}Copy the code

Functional programming is powerful, and moving to it helps you understand the benefits of JavaScript treating functions as first-class citizens.

Another language feature introduced in JavaScript is called deconstruction. Typically, you need to access a large number of properties in the component’s state or props. You can use deconstructed assignments in JavaScript instead of assigning them to variables one by one.

// no destructuring
const users = this.state.users;
const counter = this.state.counter;

// destructuring
const { users, counter } = this.state;Copy the code

This is especially useful for functional stateless components, because they can receive props objects in the function signature. Usually, you don’t use props, you use props, so you can deconstruct what’s already in the function signature.

// no destructuring
function Greeting(props) {
  return <h1>{props.greeting}</h1>;
}

// destructuring
function Greeting({ greeting }) {
  return <h1>{greeting}</h1>;
}Copy the code

Deconstruction also applies to JavaScript arrays. Another great feature is residual deconstruction. It is typically used to split a portion of an object’s attributes and keep the rest in another object.

// rest destructuring const { users, ... rest } = this.state;Copy the code

The UESRS can be rendered in the React component, and the remaining state can be used elsewhere. This is where the JavaScript spread operation comes in, passing the rest of the object to the next component.

React provides only a tiny surface area of the API, so developers have to get used to all the functionality JavaScript offers. Not without reason: “Being a React developer also makes you a better JavaScript developer”. Let’s review some of the JavaScript aspects we’ve learned by refactoring a higher-level component.

function withLoading(Component) {
  return class WithLoading extends {
    render() {
      const { isLoading, ...props } = this.props;

      if (isLoading) {
        return <p>Loading</p>;
      }

      return <Component { ...props } />;
    }
  }
  };
}Copy the code

This higher-order component is used to display the conditional loading progress bar when isLoading is set to true, otherwise the input component is rendered. You can see the (remaining) deconstruction and expansion operators in action here. The latter can be seen in the rendered Component because the remaining properties of the Props object are passed to that Component.

The first step to making higher-order components simpler is to refactor the returned React class component into a functional stateless component:

function withLoading(Component) { return function ({ isLoading, ... props }) { if (isLoading) { return <p>Loading</p>; } return <Component { ... props } />; }; }Copy the code

As you can see, residual deconstruction can also be used in the signature of a function. Next, use the JavaScript ES6 arrow function to make higher-order components even more concise:

const withLoading = Component => ({ isLoading, ... props }) => { if (isLoading) { return <p>Loading</p>; } return <Component { ... props } />; }Copy the code

The body of a function can be reduced to a single line of code by using a ternary operator. Therefore, you can omit the function body and return statement.

const withLoading = Component => ({ isLoading, ... props }) => isLoading ? <p>Loading</p> : <Component { ... props } />Copy the code

As you can see, higher-order components use a variety of JavaScript instead of React related technologies: arrow functions, higher-order functions, ternary operators, and deconstruction and expansion operators.

https://www.robinwieruch.de/javascript-fundamentals-react-requirements/

The front-end technology is evolving rapidly, but there is still the problem of large applications facing each other. EBay’s solution: Use the React stack to break down the complexity of large applications and break large projects into loosely coupled modules. Use code generation from Rekit IDE development tools to ensure consistent best practices and use refactoring tools for fast refactoring to develop large, scalable and maintainable React applications.

We can pay attention to QCon and explore the way of front-end development from three aspects: front-end architecture experience accumulated in practice, typical front-end framework application experience, new framework and design ideas. Ten percent discount registration, 680 yuan immediately reduced. Hanna, ticketing Manager, tel: 010-84782011, wechat: QCON-0410.