React technical principles and code development practice: creation and use of React components

1. Background Introduction

Overview

React is a JavaScript library for building user interfaces. It is designed to separate the UI layer and state logic and provide a concise and flexible API. When Facebook launched React in 2013, it was intended to replace Backbone and AngularJS. In order to better understand React, you need to understand some basic knowledge first. This article will explain the working principle of React and its component mechanism.

Why should we learn React?

If you already have some programming experience, you may be asking yourself: “Can I use React to write an application or website?”, “Why should I choose React over other frameworks?”. This article will give readers an overall understanding of React by comparing the advantages and disadvantages of React and other JavaScript frameworks. At the same time, by writing sample codes, readers can quickly get started and understand the concepts and syntax of React. Therefore, reading this article will not take you too much time and the content is step-by-step.

Features of React

React has the following main features:

  1. Virtual DOM: React uses virtual DOM to track changes and only update the parts that have actually changed, thereby avoiding unnecessary re-rendering and improving performance.

  2. Components: React divides the UI into independent components, which allows components to be reused and facilitates unit testing by developers.

  3. JSX: JSX is an XML-like markup language that makes it easier for React to describe what a UI should look like.

  4. Unidirectional Data Flow: React implements unidirectional data flow. The parent component only allows child components to pass data to it, not the other way around.

  5. Flexible Rendering API: There are two rendering methods: ReactDOM and React Native, which can be flexibly applied according to needs.

  6. State Management Tools: React provides a series of state management tools, such as Redux, MobX, etc.

React’s component mechanism

React’s component mechanism divides a large page or function into multiple small, reusable components. These components only focus on their own data and business logic, and communicate with each other through props. It is the component’s responsibility to define its own views, state, and behavior while trying to remain as pure as possible. Components can also provide extensible interfaces through life cycle methods to support more functions.

React components are composed of three parts:

  1. state: Each component has a state that stores the current property values and triggers UI updates. When the state changes, the component will re-render.

  2. props (properties): The way to transfer data between different components is called props, which are configuration parameters passed in from the outside.

  3. render method: The render() method is responsible for rendering the component and returning a JSX object, which determines the UI content ultimately presented by the component.

When the component’s state or props change, the render() method will be re-executed, causing the UI to be updated. Communication between components is usually achieved through props. Components can only pass data downward, not in the reverse direction, which ensures one-way flow of data.

To summarize, React’s component mechanism consists of three parts: state, properties, and rendering functions. Each component has its own data state, which may be updated by external parameters or its own state changes; the rendering function is responsible for outputting a JSX object, which describes the UI content that the component should present; the JSX object in the rendering function It will be rendered into the actual UI, and the actual UI is determined by the component’s status, properties, events, etc.

2. Core concepts and connections

JSX

JSX (Javascript + XML) is a markup language similar to XML, but it is not a new language, but embeds JavaScript expressions in JSX. React uses JSX to describe the structure of UI components. The basic syntax rules of JSX are as follows:

  • JSX elements start and end with <, , {...}.

  • JS expressions can be used in JSX tags.

  • JSX can be converted into createElement function calls.

  • JSX elements must be closed.

const element = <h1>Hello World!</h1>;

// React will compile JSX into createElement function
//The following are equivalent
ReactDOM.render(
  React.createElement('h1', null, 'Hello World!'),
  document.getElementById('root')
);

Component component

Components are the basic building blocks of React applications, and all UIs are composed of components. Each component defines its own properties, such as text content, color, size, animation effects, etc. Components can also be nested within other components to form complex page layouts. Data is passed between components through Props, which can achieve loose coupling and high cohesion.

Life cycle method

Lifecycle is an important feature of React components, which provides many callback functions about component state and behavior. It can help developers handle some specific scenarios, such as componentDidMount. This callback function will be called immediately after the component is rendered to the interface. The state of the component includes the state during initialization, the state after modification, and the state obtained after loading asynchronous data. React components have seven different stages of life cycle, namely Mounting, Updating, and Unmounting.

3. Detailed explanation of core algorithm principles, specific operation steps and mathematical model formulas

Create component

React components are defined by a file, the file name must start with a capital letter, and use JSX to describe the structure and content of the component. First create a file called MyComponent and introduce React into it:

import React from "react";

Then define the MyComponent class and export it:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    // Initialize the state of the component or bind event listeners, etc.
  }

  render() {
    return (
      <div className="my-component">
        {/* JSX of the component */}
      </div>
    );
  }
}

export default MyComponent;

React components can inherit from other components. Unless otherwise specified, their base classes are React.Component. In the constructor, we usually initialize the component's state and bind event listeners.

Rendering component

The JSX of the component describes the structure and content of the component. We can directly reference the component in the React template:

<div>
  <MyComponent />
</div>

The component MyComponent will be rendered in the div tag. Note that the tag name here must be consistent with the component name, that is, PascalCase.

State

The state of a component refers to the changes in the internal data of the component. We can set the initial state and modify it in subsequent operations. Component state is immutable and can only be updated through the setState() method. The setState() method receives two parameters. The first parameter is an object, indicating the state field that needs to be updated. The second parameter is a callback function, indicating the task to be performed after the status is updated.

this.setState({ count: this.state.count + 1 });

Props

Props is a way for parent components to pass data to child components. It is a read-only object that can only be set and read by the parent component. Child components can obtain the Props data of the parent component through this.props.

function Greeting(props) {
  return <h1>{props.name}</h1>;
}

function App() {
  return <Greeting name="John" />;
}

In the above example, the App component serves as the root component, and the Greeting component serves as a child component of the App component. The Greeting component obtains the name passed by the parent component through props and displays it on the page.

Ref

Ref is an optional property that accesses a component instance or a DOM node. We can use the ref attribute to get a reference to the underlying DOM node, through which we can manipulate the component's style, animation, position, etc. The ref attribute should be used on class components and cannot be used on function components.

class TextInput extends React.Component {
  constructor(props) {
    super(props);

    this.inputElement = React.createRef();
  }

  handleClick = () => {
    console.log("Clicked");
    this.inputElement.current.focus();
  };

  render() {
    return (
      <div>
        <input type="text" ref={this.inputElement} />
        <button onClick={this.handleClick}>Focus Input</button>
      </div>
    );
  }
}

The TextInput component is a class component that uses the input tag in JSX and assigns the reference of the underlying DOM node to a variable inputElement through the ref attribute. The handleClick function will print the log when the button is clicked and move the focus to the input box.

Life Cycle Methods

Lifecycle is an important concept in React, which provides us with many methods about component lifecycle. React provides seven different life cycle methods, which correspond to the component creation process, rendering process, update process, and destruction process. These seven methods can help us better control the state of components and handle the logic in certain specific scenarios.

1. componentWillMount()

This method is called when the component is about to be loaded into the dom tree. We can perform AJAX requests, initialization status, binding event listeners, etc. in this method. But don't setState() in this method to prevent an infinite loop.

componentWillMount() {
  fetch('/api/data')
   .then((response) => response.json())
   .then((data) => {
      this.setState({ data });
    })
   .catch((error) => {
      console.error(error);
    });
}
2. componentDidMount()

This method is called after the component is loaded into the dom tree. At this time, the component has completed rendering and can perform animations, bind third-party plug-ins, etc. This method calls the componentDidUpdate() method immediately after the componentDidMount() method.

componentDidMount() {
  const node = ReactDOM.findDOMNode(this.refs.scrollArea);
  if (node!== null) {
    Scrollbar.init(node);
  }
}
3. shouldComponentUpdate()

This method is called before each component is updated. If false is returned, the component will not be rendered. We can use this method to control the number of renderings of the component and reduce unnecessary updates.

shouldComponentUpdate(nextProps, nextState) {
  return true;
}
4. componentDidUpdate()

This method is called after the component is updated. You can perform animations, update the dom tree, request data, etc. in this method.

componentDidUpdate() {
  const el = document.querySelector("#chart");
  new Chart(el, {...});
}
5. componentWillUnmount()

This method is called before the component is unloaded and destroyed. We can perform some cleanup work, such as removing timers, unbinding event listeners, etc.

componentWillUnmount() {
  clearInterval(this.intervalId);
}
6. getDerivedStateFromProps()

This method is a static method, we can use this method to achieve the derivation of state.

static getDerivedStateFromProps(nextProps, prevState) {
  let newState = {};
  if (nextProps.value!== prevState.prevValue) {
    newState.prevValue = nextProps.value;
    newState.valueToDisplay = computeValueToDisplay(newState.prevValue);
  }
  return newState;
}
7. getSnapshotBeforeUpdate()

This method is called before the component is updated. We can get a snapshot of the DOM and save it. In the componentDidUpdate() method, we can use the snapshot to calculate and display the difference before and after the component is changed.

getSnapshotBeforeUpdate(prevProps, prevState) {
  if (this.listRef.current) {
    return this.listRef.current.scrollHeight;
  } else {
    return null;
  }
}

componentDidUpdate(prevProps, prevState, snapshot) {
  if (snapshot!== null & amp; & amp; this.listRef.current) {
    this.listRef.current.scrollTo(0, snapshot);
  }
}

PropTypes

PropTypes is a validator that describes propTypes attributes. During the development process, we can use propTypes to type-check the props parameters of the component to ensure that the variables in the running environment meet the requirements.

import PropTypes from 'prop-types';

class Greeting extends React.Component {
  static propTypes = {
    name: PropTypes.string.isRequired,
    age: PropTypes.number,
    email: PropTypes.string,
  };

  render() {
    return <h1>Hello, {this.props.name}, how are you?</h1>;
  }
}

The propTypes attribute defines three attributes: string, number, and email address. isRequired means that the attribute is required, that is, it must be passed to be valid.