Summary of Three Writing Methods of React Component

  • 2021-07-10 18:42:00
  • OfStack

React focuses on view layer, while componentization is the foundation of React and one of its core concepts. A complete application will be assembled from independent components.

Up to now, React has been updated to v15.4. 2. Due to the popularity of ES6 and the influence of different business scenarios, we will find that there are mainly three ways to create React components: 1. ES5 writing React. createClass, 2. ES6 writing React. Component, and 3. Stateless functional writing (pure component-SFC).

What kind of writing do you like best? Each team has its own code specification and development mode, but when writing React components, it will be based on the principle of improving code readability, better component performance and easy bug tracking. Let's talk about the differences between these three ways of writing and the best practices of their respective scenarios.

ES5-Writing React. createClass

Needless to say, we first used this method to build a component "class", which accepted an object as a parameter, and an render method must be declared in the object. render returns a component instance. Let's take an example of an SwitchButton component to see the specific usage of React. createClass:


var React = require('react');
var ReactDOM = require('react-dom');
var SwitchButton = React.createClass({
 getDefaultProp:function() {
 return { open: false }
 },
 getInitialState: function() {
 return { open: this.props.open };
 },
 handleClick: function(event) {
 this.setState({ open: !this.state.open });
 },
 render: function() {
 var open = this.state.open,
  className = open ? 'switch-button open' : 'btn-switch';

 return (
  <label className={className} onClick={this.handleClick.bind(this)}>
  <input type="checkbox" checked={open}/>
  </label>
 );
 }
});
ReactDOM.render(
 <SwitchButton />,
 document.getElementById('app')
);

ES6-Writing React. Component

After React is upgraded to v 0.13, it supports class syntax of ES 6. We can use class App extends React. Component {...} to create components, which is also the officially recommended way to create stateful components at present. Rewrite the above example of SwitchButton component with ES6:


import React from 'react'
import { render } from 'react-dom'
class SwitchButton extends React.Component {
 constructor(props) {
 super(props)
 this.state = {
  open: this.props.open
 }
 this.handleClick = this.handleClick.bind(this)
 }
 handleClick(event) {
 this.setState({ open: !this.state.open })
 }
 render() {
 let open = this.state.open,
  className = open ? 'switch-button open' : 'btn-switch'
 return (
  <label className={className} onClick={this.handleClick}>
  <input type="checkbox" checked={open}/>
  </label>
 )
 }
}
SwitchButton.defaultProps = {
 open: false
}
render(
 <SwitchButton />,
 document.getElementById('app')
)

Different from React. createClass creating components:

import

Here, import statement of ES6 is used instead of require () method to import module, where import {render} can directly import variable names from module, which is more concise and intuitive.

Initialize state

When React is implemented using the "class" inheritance of ES6, the hook function getInitialState is removed, and the initialization of state is declared in the constructor method constructor.

this binding

React. Component When creating a component, the event function does not bind this automatically, so we need to bind it manually, otherwise this will not point to the instance object of the current component. There are three ways to bind this:

1. Hard binding with bind () in constructor


constructor() {
 this.handleClick = this.handleClick.bind(this);
}

2. Use the bind () binding directly on the element

<label className={className} onClick={this.handleClick.bind(this)}>

3. ES6 has a very useful syntax sugar: Arrow Function (arrow function), which makes it easy for this to point directly to class SwitchButton (its function is equivalent to the familiar var self = this, but the latter will make the code confusing, and Arrow E113EN solves this problem well)

<label className={className} onClick={()=>this.handleClick()}>

Stateless functional writing (pure component SFC)

React. createClass and React. Component can both be used to create stateful components, while stateless components-Stateless Component was introduced after v 0.14 by React.

Its appearance is because with the continuous improvement of application complexity and the increase of the number of components, components are divided into different types according to their respective responsibilities, so a pure component that is only responsible for display appears. Its characteristic is that it does not need to manage the state state, and data is directly transmitted through props, which is also in line with the idea of one-way data flow of React.

For such stateless components, using functional declaration will make the code more readable and greatly reduce the amount of code. Arrow Function is the best partner of functional writing:


const Todo = (props) => (
 <li
 onClick={props.onClick}
 style={{textDecoration: props.complete ? "line-through" : "none"}}
 >
 {props.text}
 </li>
)

With the Todo component defined above, the input and output data are completely determined by props without any side effects. We can also use the deconstruction assignment of ES6 when props is of type Object:


const Todo = ({ onClick, complete, text, ...props }) => (
 <li
 onClick={onClick}
 style={{textDecoration: complete ? "line-through" : "none"}}
 {...props}
 >
 {props.text}
 </li>
)

Stateless component 1 is generally used with high-level component (abbreviated as OHC) 1, which is used to host state. Redux framework manages data sources and all states through store, in which all components responsible for presentation are written in stateless functional expression.

This pattern is encouraged to divide the originally huge components in a simple way in large projects, and the future React will also make some special optimizations for such stateless components, such as avoiding meaningless checking or memory allocation. Therefore, it is recommended that you use stateless components in your project as much as possible.

Of course, stateless components are not a panacea. For example, it does not support "ref". The reason is very simple, because the components will not be instantiated before React calls it, and naturally there is no "ref". (ref and findDOMNode actually break the convention that father and son components only pass state through props, which violates the principle of React and needs to be avoided).

Comparison of the above three writing methods and best practices

Facebook officially stated that ES6React. Component will replace React. createClass. With the continuous development of React, React. createClass exposed one problem:

Compared with React. Component, which can selectively bind required functions, React. createClass automatically binds functions, which leads to unnecessary performance overhead. React. createClass's own mixin and React. Component are no longer supported. In fact, mixin is not elegant and intuitive. The alternative is to use the more popular high-level component-HOC. If your project is still inseparable, you can also use react-mixin

Generally speaking, the stateless functional expression is better than React. createClass, while React. createClass is better than React. Component.


Related articles: