Three ways to create components in React and their differences

Stateless functional components

Creating a stateless functional component form has been around since React 0.14version. It is to create a pure display component, which is only responsible for propsdisplaying according to the incoming, and does not involve statethe operation of the state. The specific stateless functional component , its official point out:

   在大部分React代码中,大多数组件被写成无状态的组件,通过简单组合可以构建成其他的组件等;这种通过多个简单然后合并成一个大应用的设计模式被提倡。

A stateless functional component formally represents a rendercomponent class with only one method, created by a function or ES6 arrow function, and the component is statestateless. The specific creation form is as follows:

function HelloComponent(props, /* context */) {
  return <div>Hello {props.name}</div>
}
ReactDOM.render(<HelloComponent name="Sebastian" />, mountNode) 

The creation of stateless components makes the code more readable, reduces a lot of redundant code, and reduces it to only one render method, which greatly enhances the convenience of writing a component. In addition, stateless components also have The following salient features:

  1. The component will not be instantiated, and the overall rendering performance is improved
    because the component is simplified into a function of the render method. Since it is a stateless component, the stateless component will not be in the process of component instantiation, without instantiation. The process does not need to allocate extra memory, so the performance is improved to a certain extent.
  2. Components cannot access thisobjects
    Stateless components cannot access objects in this component because they have no instantiation process, such as: this.ref, this.stateetc. You cannot use this form to create a component if you want to access it
  3. Components cannot access lifecycle methods
    Because stateless components do not require component lifecycle management and state management, the underlying implementation of this form of components will not implement component lifecycle methods. Therefore, stateless components cannot participate in the various lifecycle management of components.
  4. Stateless components can only access the input props, the same props will get the same rendering result without side effects

Stateless components are encouraged to split the original huge components in a simple way in large projects. In the future, React will also perform a series of optimizations for stateless components in areas such as meaningless checks and memory allocation, so as long as there are When possible, try to use stateless components .

React.createClass

`React.createClass`是react刚开始推荐的创建组件的方式,这是ES5的原生的JavaScript来实现的React组件,其形式如下:
var InputControlES5 = React.createClass({
    propTypes: {//定义传入props中的属性各种类型
        initialValue: React.PropTypes.string
    },
    defaultProps: { //组件默认的props对象
        initialValue: ''
    },
    // 设置 initial state
    getInitialState: function() {//组件相关的状态对象
        return {
            text: this.props.initialValue || 'placeholder'
        };
    },
    handleChange: function(event) {
        this.setState({ //this represents react component instance
            text: event.target.value
        });
    },
    render: function() {
        return (
            <div>
                Type something:
                <input onChange={this.handleChange} value={this.state.text} />
            </div>
        );
    }
});
InputControlES6.propTypes = {
    initialValue: React.PropTypes.string
};
InputControlES6.defaultProps = {
    initialValue: ''
};

In contrast to stateless components, React.createClassand described later React.Componentare all about creating stateful components that are instantiated and have access to the component's lifecycle methods. But with the development of React, React.createClassthe problems of the form itself were exposed:

  • React.createClass will self-bind function methods (unlike React.Component which only binds functions that need to be cared about), causing unnecessary performance overhead and increasing the possibility of code obsolescence.
  • The mixins of React.createClass are not natural and intuitive; the form of React.Component is very suitable for higher order components (Higher Order Components--HOC), it shows more powerful functions than mixins in a more intuitive form, and HOC is pure JavaScript, Don't worry about them being scrapped. HOC can refer to stateless components (Stateless Component) and higher-order components .

React.Component

React.ComponentReact components are created in the form of ES6, which is currently highly recommended by React to create stateful components, and will eventually replace the React.createClassform; it  React.createClasscan better achieve code reuse. Change the above React.createClassform to the React.Componentfollowing form:

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

        // 设置 initial state
        this.state = {
            text: props.initialValue || 'placeholder'
        };

        // ES6 类中函数必须手动绑定
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(event) {
        this.setState({
            text: event.target.value
        });
    }

    render() {
        return (
            <div>
                Type something:
                <input onChange={this.handleChange}
               value={this.state.text} />
            </div>
        );
    }
}
InputControlES6.propTypes = {
    initialValue: React.PropTypes.string
};
InputControlES6.defaultProps = {
    initialValue: ''
};

The difference between React.createClass and React.Component

In addition to the difference in the syntax format of the two components defined in the code shown above, there are many important differences between the two. The main differences between the two are described below.

function this self-binding

React.createClassFor the created component, the this of each member function is automatically bound by React. You can use it at any time, this.methodand the function thiswill be set correctly.

const Contacts = React.createClass({  
  handleClick() {
    console.log(this); // React Component instance
  },
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }
});

React.ComponentThe member function of the created component will not automatically bind this, and the developer needs to bind it manually, otherwise this cannot obtain the current component instance object.

class Contacts extends React.Component {  
  constructor(props) {
    super(props);
  }
  handleClick() {
    console.log(this); // null
  }
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }

Of course, React.Componentthere are three ways to do manual binding: you can do the binding in the constructor, you can use it when you call it method.bind(this), and you can use the arrow function to do it. Take the handleClickfunction in the example above, its bindings can have:

    constructor(props) {
       super(props);
       this.handleClick = this.handleClick.bind(this); //构造函数中绑定
  }
    <div onClick={this.handleClick.bind(this)}></div> //使用bind来绑定
    <div onClick={()=>this.handleClick()}></div> //使用arrow function来绑定

The component property type propTypes and its default props property defaultProps are configured differently

React.createClassWhen creating a component, the property type of the component props and the default properties of the component will be configured as the properties of the component instance , where defaultProps is getDefaultPropsthe method used to obtain the default component properties

const TodoItem = React.createClass({
    propTypes: { // as an object
        name: React.PropTypes.string
    },
    getDefaultProps(){   // return a object
        return {
            name: ''    
        }
    }
    render(){
        return <div></div>
    }
})

React.ComponentWhen configuring these two corresponding information when creating a component, they are configured as properties of the component class , not properties of the component instance, that is, the so-called static properties of the class . Corresponding to the above configuration as follows:

class TodoItem extends React.Component {
    static propTypes = {//类的静态属性
        name: React.PropTypes.string
    };

    static defaultProps = {//类的静态属性
        name: ''
    };

    ...
}

The configuration of the component's initial state state is different

React.createClassThe state of the created component is to configure the component-related state through getInitialStatemethods; the state of
React.Componentthe created component is constructordeclared in the same way as initializing the component properties.

const TodoItem = React.createClass({
    // return an object
    getInitialState(){ 
        return {
            isEditing: false
        }
    }
    render(){
        return <div></div>
    }
})
class TodoItem extends React.Component{
    constructor(props){
        super(props);
        this.state = { // define this.state in constructor
            isEditing: false
        } 
    }
    render(){
        return <div></div>
    }
}

Mixins are supported differently

Mixins(Mixing) is an implementation of object-oriented programming OOP. Its function is to reuse the common code, extract the common code into an object, and then Mixinsachieve code reuse by entering the object. For details, please refer to the past and present of React Mixin .

React.createClassProperties can be used when creating components mixinsto mix in a collection of classes in the form of an array.

var SomeMixin = {  
  doSomething() {

  }
};
const Contacts = React.createClass({  
  mixins: [SomeMixin],
  handleClick() {
    this.doSomething(); // use mixin
  },
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }
});

But unfortunately, React.Componentthis form is not supported Mixins. So far, the React team has not given an official solution in this form; but the React developer community provides a new way to replace Mixinsit, that is, Higher-Order Components , the specific details can be refer to this article

How to choose which way to create components

As the React team has stated that React.createClass will eventually be replaced by the class form of React.Component. But forms Mixinsare not discarded until an alternative is found React.createClass. so:

能用React.Component创建的组件的就尽量不用React.createClass形式创建组件。

In addition, the choice of form to create components should also be determined according to the following:

1、只要有可能,尽量使用无状态组件创建形式。

2、否则(如需要state、生命周期方法等),使用`React.Component`这种es6形式创建组件

add another point

In fact, the function can be used inside the stateless component ref. Although it cannot be this.refsaccessed, it can be obtained by saving the ref content to a local variable inside the stateless component.

For example, the following code can use ref to get the dom element pointed to after the component is mounted in the dom:

function TestComp(props){
    let ref;
    return (<div>
        <div ref={(node) => ref = node}>
            ...
        </div>
    </div>)
}

references

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325776192&siteId=291194637