Some time ago, I encountered such a scenario when writing Hybrid pages at work. The company needed a series of active components, and an interface provided by the App side was called when each component was registered. Several approaches were considered initially, including mixins, component inheritance, and React higher-order components. But after a variety of measures, the final choice is to use higher-order components.

The downside of Mixins

React does not recommend the use of Mixins for code reuse. Mixins have a number of disadvantages. First, Mixins can cause naming conflicts.

var myMixins = require('myMixins');

var Button = React.createClass({
    mixins: [myMixins],
    
    // ...
})
Copy the code

If you need to inject multiple mixins, one of them is your own, and the others may be third-party. It’s possible to use a method with the same name in two mixins, which makes one of them invalid, and all you can do is change the name of one of the methods. On the other hand, a mixins may start out simple, with only one function to implement, but become very complex as the business becomes more complex and more methods need to be added to it. For an in-depth look at mixins’ shortcomings, check out the official blog.

2. Component inheritance

For me this way before use, first create a BaseComponent, implement a series of public methods, in which each component of the following are inherited from the component, but the disadvantage is that not enough flexible, can only achieve some relatively fixed in the basic component method, customized for each component will have a lot of restrictions.

React Advanced components

Due to the drawbacks of mixins, React officials also realize that the pain points of using mixins far outweigh the benefits of the technology itself, and that higher-level components can replace mixins, and that they can be used in a variety of ways.

HOC is an advanced technology for reusing component logic in React. But the higher-order components themselves are not the React API. It’s just a pattern, and that pattern is necessarily generated by the combinatorial nature of React itself.

Higher-order functions

Speaking of higher-order components, it is necessary to speak of higher-order functions first. Higher-order functions are functions that satisfy at least the following conditions:

1. Take one or more functions as input. 2

In javascript, which is a first-class citizen language, the use of higher-order functions is very much, such as our usual callback function and so on, have used the knowledge of higher-order functions. Let’s start with a simple higher-order function

var fun = function(x, y) {
    return x + y;
}
Copy the code

Fun is a function, and now we pass the whole function as an argument to another function

var comp = function(x, y, f) {
    return f(x,y);
}
Copy the code

verify

Comp (1, 2, fun) / / 3Copy the code
High-level component definition

Analogous to the definition of higher-order functions, higher-order components take a component as an argument, do a series of things to the component in the function, and then return a new component as the return value.

Let’s start by defining a high-level component, BaseActivity

const BaseActivity = (WrappedComponent) => {
  return class extends Component {
    render() {
      return(<section> <div> my WrappedComponent </div> <WrappedComponent /> </section>)}}}Copy the code

The component takes a wrapped component as an argument and returns a processed anonymous component. Use this higher-order component in other components

class Example extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      width: '100%',
      height: '100%'}}componentWillMount() {
    if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fenne c|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {return;
    } else {
      this.setState({
        width: '375px',
        height: '640px'}}})render() {
    let { width, height } = this.state;
    return (
      <div className="activity">
        <div className="activity-content" style={{ width, height }}>
          <button className="btn"</button> </div> </div>)}}export default BaseActivity(Example);
Copy the code

When exporting the component, use BaseActivity to wrap the component. See the react DOM output

An anonymous component is wrapped around the Example component.

parameter

Since the higher-order component is a function, we can pass in the parameters we need

const BaseActivity = (WrappedComponent, title) => {
  return class extends Component {
    render() {
      return (
        <section>
          <div>{title}</div>
          <WrappedComponent />
        </section>
        
      )
    }
  }
}
Copy the code

Export in Example

export default BaseActivity(Example, 'Here are the higher-order component parameters');
Copy the code

Let’s look at the react DOM output

You can see that the parameters have been passed in.

And of course you can use it this way (Currization)

const BaseActivity (title) => (WrappedComponent) => {
  return class extends Component {
    render() {
      return (
        <section>
          <div>{title}</div>
          <WrappedComponent />
        </section>
        
      )
    }
  }
}
Copy the code

Export in Example

export default BaseActivity('Here are the higher-order component parameters')(Example);
Copy the code

This usage can be seen in ant-Design forms as well as redux’s Connect

// ant
const WrappedDemo = Form.create()(Demo)

// redux
export default connect(mapStateToProps, mapDispatchToProps)(Counter)
Copy the code

Higher-order components can also extend the props property of the original component, as shown below:

const BaseActivity (title) => (WrappedComponent) => {
  return class extends Component {
    render() {
      const newProps = {
          id: Math.random().toString(8)
      }
      return( <section> <div>{title}</div> <WrappedComponent {... this.props} {... newProps}/> </section> ) } } }Copy the code

Take a look at the react DOM output

Disadvantages of higher-order components

Higher-order components also have a number of disadvantages. The first is that the static method of the wrapped component will disappear. This is actually quite understandable. If we want to preserve it, we can manually copy the methods of the original component to the new component, or use a library like hoist-non-react-statics for copying.

conclusion

Higher-order functions may not be easy for beginners to understand, but once you get into them and understand how they work, there’s a lot we can do with higher-order functions.

If you like, please follow my Blog, give a Star, and share some JS knowledge regularly, ^_^