简体   繁体   中英

Spreading props in React Higher Order Components

I am trying to go very in-depth to understand the purpose of spreading props in React HOC

So taking the below example;

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

export default EnhanceComponent;

Now let's say the usage of BaseComponent is as below;

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

I assume if had not spread the props in the HOC, we would have been unable to access "this.props.className" OR "this.props.onClick" in BaseComponent. Would that be correct understanding?

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

         ...
      }
   }

Now to use the HOC itself, we would say;

const EnhancedMyComponent = EnhanceComponent(MyComponent);

And render it as

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

Now, below are my 2 specific questions;

  1. What do we finally render ie BaseComponent or EnhancedMyComponent OR using HOC allows us to use either flavor eg in some case, if we do not want the enhanced functionality, we just use the base component?

OR

<EnhancedMyComponent className='wrapper-container' onClick={this.handleClick} />
  1. Would the props access issue ie if we do not spread the props be applicable in both the above cases of consumption ie <BaseComponent /> AND <EnhancedMyComponent /> ?

1) What do we finally render ie BaseComponent or EnhancedMyComponent OR using HOC allows us to use either flavor eg in some case, if we do not want the enhanced functionality, we just use the base component?

/ Using HOC allows us to use either flavor. It totally depends where we are wrapping the Component in HOC ie while exporting or while using it at someplace.

Now, In the below case one has the option to use it with or without HOC

// BaseComponent.js 
        class BaseComponent extends React.Component {
                  render() {
                     const { className, onClick} = this.props;
            
                     ...
                  }
               }
    export default BaseComponent;
    
    // SomeComponent.js
    import BaseComponent from './BaseComponent';

    const MyComponent = EnhanceComponent(BaseComponent);
    class SomeComponent extends React.Component {
                  render() {
                     return ( 
                     ...
                     <MyComponent className={...} onClick={...} someExtraPropForHOC={...}/>
                     <BaseComponent  className={...} onClick={...} />
                     ...
                  )
               }

To not allow anyone to directly use the Component, wrap it in HOC and export

// BaseComponent.js 
    class BaseComponent extends React.Component {
              render() {
                 const { className, onClick} = this.props;
        
                 ...
              }
           }
export default EnhanceComponent(BaseComponent);

// SomeComponent.js
import BaseComponent from './BaseComponent';
class SomeComponent extends React.Component {
              render() {
                 return ( 
                 ...
                 <BaseComponent className={...} onClick={...}/>
                 ...
              )
           }

2) Would the props access issue ie if we do not spread the props be applicable in both the above cases of consumption ie AND?

/ Spread the props is needed as HOC does not know what props would be needed for the dynamically wrapped component. So pass all the props which are coming is the only possible way.

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

         ...
      }
   }

class CustomTextField extends React.Component {
      render() {
         const { className, onKeyPress, value} = this.props;

         ...
      }
   }

const EnhancedBaseComponent = EnhanceComponent(BaseComponent);
const EnhancedTextComponent = EnhanceComponent(CustomTextField);

Now in this case EnhancedBaseComponent and EnhancedTextComponent both need different props, but since they are wrapped in EnhanceComponent. It won't know which props to pass. So spread it and send all the props coming to it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM