Higher-order components vs higher-order functions

First, HOC high-order components vs high-order functions:

Higher-order components are those that take one component as an argument and return another

Higher-order functions: take one function as an argument and return another function

The role of higher-order components

Reuse component logic

[Real] Processing empty data

In a real world scenario, a common problem is that if the field returned by the back end is null/ empty for some reason, it will not be displayed on the page.

One solution would be to replace these empty fields with others, such as’ empty ‘/’ — ‘etc.

I am tired of iterating through the substitution of null characters every time I present data.

At this point, we need to reuse the “null character replacement” logic, write a simple higher-order component:

1. Requirement: Replace null characters with ‘–‘

Const withEmptyData = (WrappedComponent) => New component

Higher-order components:

const withEmptyData = (WrappedComponent) = > {
    return class extends Component {
        handleProps = (props) = > {
            constnewProps = {... props};for (let key in props) {
                newProps[key] = props[key] === null ? 'empty' : props[key]
            }
            return newProps;
        }
        render() {
            return <WrappedComponent {. this.handleProps(this.props)} / >}}}Copy the code

How to use:

const Item = ({name, age, address}) => {
    return (
        <div>
           name: {name} --- age:{age} --- address:{address}
        </div>
    )
}

const WithEmptyItem = withEmptyData(Item)
Copy the code

Show a new component:

const mockData = {
    name: 'rose', age: null, address: null } const Test = () => <WithEmptyItem {... mockData}/>Copy the code

Final presentation:

Name :rose -- age: empty -- address: emptyCopy the code

2. Requirement: you can customize the data displayed when the field is empty

Const withEmptyData = (WrappedComponent, emptyText) => new component

Higher-order components:

const withEmptyData = (WrappedComponent, emptyText) = > {
    return class extends Component {
        handleProps = (props) = > {
            constnewProps = {... props};for (let key in props) {
                newProps[key] = props[key] === null ? emptyText : props[key]
            }
            return newProps;
        }
        render() {
            return <WrappedComponent {. this.handleProps(this.props)} / >}}}Copy the code

How to use:

const WithEmptyItem = withEmptyData(Item, 'No data at present')
Copy the code

Final presentation:

Name :rose -- age: no data is available. -- Address: No data is availableCopy the code

3. Requirement: The form of double parentheses

const withEmptyData = emptyText => WrappedComponent => {}

Remember connect(mapState,mapDispatch)(Demo), this is also a high order component, this is two parentheses, our component can also be modified to look like this!

Higher-order components:

const withEmptyData = emptyText= > WrappedComponent => {
    return class extends Component {
        handleProps = (props) = > {
            constnewProps = {... props};for (let key in props) {
                newProps[key] = props[key] === null ? emptyText : props[key]
            }
            return newProps;
        }
        render() {
            return <WrappedComponent {. this.handleProps(this.props)} / >}}}Copy the code

How to use:

const WithEmptyItem = withEmptyData('No data at present')(Item)
Copy the code

[Combat] Encapsulation loading

The loading component is displayed before the data is requested, and the normal component is displayed after the data is requested.

const withLoading = (WrappedComponent) =>{
    return class extends Component{
        render() {
            returnthis.props.loading ? <div>loading.... </div> : <WrappedComponent {... this.props}/> } } }Copy the code
const LoadingItem = withLoading(Item)
Copy the code

It’s so easy!

[Merge] Superimpose higher-order components on top of higher-order components

This is ok, since the above two requirements are both necessary, then we try to add them together! High-order components stacked on top of high-order components!

const withEmptyDataItem = withEmptyData('No data at present')(Item) const LoadingItem = withLoading(withEmptyDataItem) const Test = () => <LoadingItem loading={loading} {... mockData}/>Copy the code

In this way, empty field display and loading functions can be used.

Finally, understanding the background of higher-order components, and knowing why the concept of higher-order components emerged, may help us to choose and use them when we write code.

Of course, the actual combat is also essential!