6

I'm trying to understand React's Higher Order Component structure, but all the resources just assume you already understand what the purpose of the spread operator is doing in the higher order component when you write: BaseComponent {...this.props} {...this.state} . Why is it necessary to spread out the props like that if a component is already being passed in as props?

import React, { Component } from 'react';

const EnhanceComponent = BaseComponent => {
    return class EnhancedComponent extends Component {
        state = {
            name: 'You have been enhanced'
        }
        render() {
           return ( 
           <BaseComponent {...this.props} {...this.state} />   
        )
       }
    }
};

export default EnhanceComponent;
Dog
  • 2,120
  • 3
  • 18
  • 50

3 Answers3

3

The answer is directly explained in the docs:

Convention: Pass Unrelated Props Through to the Wrapped Component HOCs add features to a component. They shouldn’t drastically alter its contract. It’s expected that the component returned from a HOC has a similar interface to the wrapped component.

HOCs should pass through props that are unrelated to its specific concern. Most HOCs contain a render method that looks something like this:

To understand this you should know what {...this.props} does. In your case

const EnhanceComponent = BaseComponent => {
    return class EnhancedComponent extends Component {
        state = {
            name: 'You have been enhanced'
        }
        render() {
           return ( 
           <BaseComponent {...this.props} {...this.state} />   
        )
       }
    }
};

export default EnhanceComponent;

EnhanceComponent HOC does a simple operation of adding a state name to the component currently being rendered, so essentially when you use this HOC, you should be able to pass the props required by your original component directly to it rather than consuming them in the HOC, which is what {...this.props} spread syntax is for. You can read this answer for more details on how ... works

Consider the case of a simple component which is used like

<MyComponent className='wrapper-container' onClick={this.handleClick} />

and defined as

class MyComponent extends React.Component {
      render() {
         const { className, onClick} = this.props;

         ...
      }
   }

Now if you use an HOC over this component like

const EnhancedMyComponent = EnhanceComponent(MyComponent);

You would render it like

<EnhancedMyComponent className='wrapper-container' onClick={this.handleClick} />

and now if you don't write {...this.props} in your HOC, then the MyComponent will no longer have className and onClick as props

Shubham Khatri
  • 211,155
  • 45
  • 305
  • 318
1

For example you have a component and you want to enhance it:

const Message = props => (
  <div className={props.type}>
    <p>{props.message}</p>
  </div>
)

const EnhancedMessage = enhance(Message);

Then you can use enhanced component somewhere in your code:

<EnhancedMessage type="alert" message="Something went wrong" />

If you don't spread props passed to HOC how will Message component know about passed props?

user3309314
  • 2,133
  • 1
  • 15
  • 26
0

Simple answer :

Spreading props is not mandatory

If you want to keep props of a component, to be there after wrapping, then spread props in wrapper component otherwise don't spread it.