In the React world, the smallest unit that makes up a page is a set of components, and it’s clear how to create them properly is critical. Here’s my understanding and summary of the three ways to create components.

Start simple: Functional components

People who know React know that a Component data source has two:

  1. Properties from outside (props)
  2. State from within

When a component is created functionally, it is obviously doomed to no longer have its own State, and has to “mindlessly” fetch property content and display it, because a functional component is a component that only implements the Render function.

So it’s nice to call this a “little fool” component

An example of a “dumb functional component” :

// This import must be added; the JSX context depends on it
import React from 'react';

export default ({order="I don't do anything until I'm told."= > {})return (
        <div>I am the "fool component" and I follow the command completely: {order}.</div>
    );
};
Copy the code

This simple component accepts only one order and sets a default value for this property.

  1. When the component is used and the order property is set for it, the value of the order property set externally is printed;
  2. If not, the default value is printed (ES6 syntax allows setting a default value for defined function arguments)

ES6 arrow syntax is used here to quickly create a stateless functional component and exoprt it for external use.

More complex: Inherit the React Component implementation

After React version 16, the createclass method is no longer recommended for creating components. It is also recommended that higher-order functions be used instead of the intrusive code reuse method used by mixins

A component can inherit from two parent classes:

  1. React.Component
  2. React.PureComponent

PureComponent and Component behave the same except that the implementation of shouldComponentUpdate is logically different. PureComponent uses a shallow comparison of props and state.

In general we inherit react. PureComponent to optimize component performance, but in special cases you can inherit React.componentand implement the shouldComponentUpdate logic yourself.

Inherited components are smarter than dumb ones:

It can have its own properties 2. It can have its own states 3. It can have its own lifecycle logic

A simple example of a “smart” inherited component:

import React from "react";
import PropTypes from "prop-types";

export default class ComponentOne extends React.PureComponent {
  static defaultProps = {
    propOne: "Default properties"
  };

  static propTypes = {
    propOne: PropTypes.string.isRequired
  };

  constructor(props) {
    super(props);
    console.log("Constructor");
    this.clickToAdd = this.clickToAdd.bind(this);
    this.state = {
      count: 0
    };
  }

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

  componentDidMount() {
    console.log("Interface loading completed");
  }

  render() {
    return (
      <div>
          <div>I'm a component created by inheriting react. PureComponent. And I have property: {this.props. PropOne}</div>
          <div>Current count: {this.state.count}</div>
          <div>
              <button onClick={this.clickToAdd}>Click count increment</button>
          </div>
      </div>); }}Copy the code

One thing to note is that any member function of a component created using inheritance will not automatically bind this. Manual bind in constructor is recommended.

The component in the above code has its own state, its own properties, and also implements the life cycle function componentDidMount, which simply prints a log.

Worse: HOC (Higher Order Component)

A higher-order component is a function that takes a component as an argument and returns a new component. Higher-order components can be implemented in either of the following ways:

1. Proxy mode (Combination)

Take a look at the sample code:

import React from 'react';

const agent = (WrappedComponent, newProps) = > {
    return class WrappingComponent extends React.PureComponent{
        render(){
            return <WrappedComponent {. this.props} {. newProps} / >
        }
    }
}

export default agent;
Copy the code

WrappingComponent and WrappedComponent each go through their own life cycle, and a higher-order function in proxy mode is a combination of the two components.

You can use this to manipulate the incoming props to reuse code.

2. Inheritance mode (Inheritance)

Take a look at the sample code:

import React from 'react';

const OnlyForLoginComponent = (WrappedComponent) = > {
    return class WrappingComponent extends WrappedComponent{
        render(){
            if (this.props.logined) {
                return super.render();
            } else {
                return (
                    <div>Please log in first.</div>); }}}}export default OnlyForLoginComponent;
Copy the code

You can see that a new component is implemented and returned by inheritance. Higher-order components are implemented by inheritance in a two-for-one manner, so we can manipulate the WrappedComponent lifecycle and, of course, its properties.

For example, the code above shows that a high-order component is used to generate a login status component that continues to render the super (aka WrappedComponent) if logged in, otherwise prompts “please log in first”.

Those familiar with the React-Redux library can explore its connect function. The return value of this function is a higher-order component that takes a component and returns a new one.

So far, the three mainstream ways of creating new components have been summarized. These contents are also some summaries of my own learning and practice. I would like to write them down and share them with you in the hope of common progress.