This is the 25th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

preface

React Component design pattern (solution)

Higher-order components, renderProps

High-level component HOC mode

Source of reference

Similar to higher-order functions in JS, a function that takes a function as an argument, or returns a function, is called a higher-order function.

Higher-order components are components that either take a component as a parameter or return a component.

In actual application scenarios, service logic is reused and different components are displayed based on user identity types. Vips and ordinary users are common. Normally we would go back to writing the judgment logic, but higher-order components are a better solution to this problem.

PS: It’s really not about memorizing the concept, it’s about learning to use the scenario. Focus only on concepts, and you will always be a student with an engineering mindset to solve problems, that is, pragmatism.

Higher-order component concepts

const NewComponent = higherOrderComponent(OldComponent)

From a function’s point of view: The function takes a JSX component as an argument and returns a JSX

From a component perspective: a component passes through a function to form a new component (a wrapper around an existing component, with its own state and logic)

  • A function that passes in a component and returns a new component
  • There is usually no UI presentation
  • Provide some reusable functionality

The sample

Scene description

Moving the mouse in and out of a component shows a different content

withTooltip.js 

Import React from 'React' const withTooltip = (Component) => {class HOC extends React.Component {state = {// mouse in and out } handleOver = (ev)=> this.setState({showToolTip: true, content: ev.target.innerText}) handleOut = (ev)=> this.setState({showToolTip: false, content: ''}) render(){ return( <div onMouseOver={this.handleOver} onMounseOut={this.handleOut}> // Pass the received props to Component <Component Action ={this.state} {... props} /> </div> ) } return HOC } } export default withTooltipCopy the code

itemA.jsx

import React, { Component } from 'react' import withTooltip from './withTooptip' const ItemA = (props) => { return ( <div className='container' > <button className="btn btn-primary" type="btn"> Tooltip A </button> {props.action.showToolTip&&(  <span className="badge badge-pill badge-primary ml-2"> {props.action.content} </span> )} </div> ) } export default withTooltip(ItemA);Copy the code

itemB.jsx

import React, { Component } from 'react'
import withTooltip from './withTooptip'
const ItemB = (props) => {
    return (
        <div className='container'>
            <button className="btn btn-vip" type="btn"> Tooltip A </button>
            {props.action.showToolTip&&(
                <span className="badge badge-pill badge-primary ml-2">
                    {props.action.content}
                </span>
            )}
        </div>
    )
}
export default withTooltip(ItemB);
Copy the code

App.js

import React, {Component} from 'react' import ItemA from './component/hoc/itemA' import ItemB from './component/hoc/itemB' class App extends Component { constructor(props){ super(props) this.state={} } render(){ return( <> <ItemA id={1}/> {/* When passing the parameter through props, the component that receives the parameter is withTooltip*/} <ItemB /> </>)}} export default AppCopy the code

Summary of high-level component solutions

When I knocked down the whole code, I felt like he was doing something I didn’t understand with a lot of extra encapsulation. So I began to think, if I, encountered this scene, how I would use my knowledge to solve the problem.

In the first step, he decides whether to implement A’s functionality or B’s functionality without addressing the user’s identity. If you’re A type A user, let him use component A, and if you’re A type B user, let him use component B. This makes it particularly extensible, and since the business logic is not written directly on the source file, it solves the problem that the newly introduced C does not affect the mature A and B.

Higher-order components don’t make us write less code, they make us write more code. But such code is much more maintainable and extensible. He judged it from a beginner’s point of view, not as a bizarre technique, but as a more banal template. Can only understand some design patterns and design ideas, coupled with the actual encounter of similar problems to feel his charm. The template details are not discussed, but are in the comments of the relevant code.

Advanced component features

  • A function that passes in a component and returns a new component
  • There is usually no UI presentation
  • Provide some reusable functionality

Function as the child component render props

Solve the problem of reuse business logic

Use a props value of function to share the design pattern of the code between components

Red circles represent different content

The black Component represents the subcomponents, the functionality to be reused

The result is a component with red’s unique functionality and the same business logic that needs to be reused

1. Define subcomponent templates

render() {
    return (
        <div>
            {this.props.render(this.state)}
        </div>
    )
}
Copy the code

2. Use functions as the props template

<RenderPropComponent render={(state)=>(
    <div>content</div>
)}/>
Copy the code

Code sample

ItemC.jsx

import React, { Component } from 'react'; import WithTooltip from './withTooltip' const ItemC = ( props ) => { return ( <div className='container'> <WithTooltip> Render {({showToolTip, content}) => ( <div> <button className="btn btn-primary" type="btn"> Tooltip C </button> {showToolTip && ( <span className="badge badge-pill badge-primary ml-2"> {content} </span> )} </div> )} </WithTooltip> </div> ); } export default ItemC;Copy the code

withTooltip.js

import React from 'react' class WithTooltip extends React.Component { state ={ showToolTip : false, content : '' } handleOver = (ev) => this.setState({showToolTip: true, content : ev.target.innerText}) handleOut = () => this.setState({showToolTip : false, content : ''}) render() { return( <div onMouseOver={this.handleOver} onMouseOut={this.handleOut}> {this.props. Children (this.state)}} export default WithTooltip;Copy the code

App.js

import React, {Component} from 'react'
import ItemC from './component/itemC'

class App extends Component {
    constructor(props){
        super(props)
        this.state={}
    }
    render(){
        return(
            <>
                <ItemC />
            </>
        )
    }
}
export default App
Copy the code

Function as a subcomponent solution summary

The scheme seems a bit confusing, especially when you understand the first higher-order component

Higher-order components, where the withTooltip function operates directly on the old component and returns a new component with the feel of a chain call, are better suited for more complex operations.

Render Props are simple assembly + encapsulation, and are good at handling some simple operations.

Component Relationship Description

App 
    HOC
        ItemA
    HOC 
        ItemB
    ItemC
        WithTooltip
Copy the code

Conclusion:

Good difficult ah, wu Wu ~ you can refer to the reference materials written by these big guys.

I can’t learn anymore. I’ll move bricks.

The general idea is understood, but without practical operation, it leads to that there is no way to compare these two schemes, which is easy to confuse.

In conclusion, I am still a salt fish.

The resources

React component Render Props VS HOC design mode

www.jianshu.com/p/ff6b30088…

React Hooks on HoC and Render Props

zhuanlan.zhihu.com/p/62791765

React starts here. It’s finally over. At the same time, the essay contest in November is coming to an end. Based on my understanding of myself, this should be the last time for me to write this kind of essay, or I want to make one last effort to see how far I can achieve this time. Like this high frequency of more text or more suitable for college students, I really a little powerless. Can only be regarded as an unyielding old people insist on it, in memory of his last stubborn. After that, I will polish some excellent articles, polish my own system, and transfer all the competitiveness to the construction of system logic. Finally, thank you to the Nuggets for providing such a great platform and opportunity to grow. Thank you for your contribution to the technical community.