HOC is an advanced technique used in React to reuse component logic. HOC itself is not part of the React API; it is a design pattern based on the composite features of React.

Specifically, a higher-order component is a function that takes a component and returns a new component.

Similar to Vue mixins

Here’s a quick example of how HOC can be used

Chinese website address: https://react.docschina.org/docs/higher-order-components.html

1. Start by creating a hock. js file and writing the associated public logic

import React, { Component } from 'react' const Hoc = (WrappedComponent) => { return class extends Component { constructor(props) { Super (props) this.state = {// Define the reusable state count: 1,}} componentDidMount() { First load HOC's lifecycle hook function console.log('111')} // define a public reusable method getCode(num) {this.setstate ({count: num }) console.log(num) } render() { console.log(this.props) return ( <div> <WrappedComponent getCode={this.getCode.bind(this)} state={this.state} /> </div> ) } } } export default HocCopy the code

2. Then introduce HOC in other public methods or data that need to be used and pass in the component itself as a parameter

import React, { Component } from 'react'; // import HOC from './ HOC '; class MyComponentextends Component { constructor(props) { super(props); this.state = { num: 1 }; } render() { console.log('----->', this.props); return ( <div> <button onClick={() => { this.setState( (state) => { return { num: ++state.num }; }, () => {// activate the Hoc file method using the method used in the higher-order component and pass in the relevant parameter this.props. GetCode (this.state.num); }); }} > < / button > / / obtain the HOC value < h1 style = {{color: 'red'}} > {this. Props. State. The count} < / h1 >); }} //MyComponent is passed as an argument to the HOC function export default HOC (MyComponent);Copy the code

According to the above steps, the general function of HOC has been preliminarily realized

Pay attention to the point

1. Don’t change the original component, use composition.

Instead of trying to modify a component prototype (or otherwise change it) in HOC, implement functionality by wrapping components in container components

function logProps(WrappedComponent) { return class extends React.Component { componentDidUpdate(prevProps) { console.log('Current props: ', this.props); console.log('Previous props: ', prevProps); } render() {// Wrap the input component in a container without modifying it. Good! return <WrappedComponent {... this.props} />; }}}Copy the code

2. Convention: Pass the unrelated props to the wrapped component

HOC adds features to components. They should not change their agreements drastically. The component returned by HOC should maintain a similar interface to the original component.

HOC should pass through props that have nothing to do with itself. Most HOC should include a render method like the one below: this convention ensures that HOC is flexible and reusable.

Render () {// Filter out props not on this HOC, and do not pass const {extraProp,... passThroughProps } = this.props; // Inject props into the wrapped component. // Usually the value of state or instance method. const injectedProp = someStateOrInstanceMethod; Return (<WrappedComponent injectedProp={injectedProp} {... passThroughProps} /> ); }Copy the code

3. Don’t use HOC in render methods

The React diff algorithm (called coordination) uses component identifiers to determine whether it should update an existing subtree or drop it and mount a new one. If the component returned from Render is the same as the component in the previous render (===), React updates the subtree recursively by differentiating it from the new one. If they are not equal, the previous subtree is completely unloaded.

This isn’t just a performance issue – remounting a component causes a loss of state for that component and all its children.

If you create HOC outside of the component, then the component will only be created once. Therefore, the same component is rendered each time. Generally speaking, this is in line with your expected performance.

In rare cases, you need to invoke HOC dynamically. You can make the call in a component’s lifecycle method or in its constructor.

Refs will not be passed

Although the convention for higher-order components is to pass all props to the wrapped component, this does not apply to refs. That’s because a REF isn’t really a prop – like a key, it’s handled specifically by React. If you add ref to HOC’s return component, the REF reference points to the container component, not the wrapped component.