BeardMagician
BeardMagician

Reputation: 657

Higher Order Component can't access Wrapped Component's default props

I have an HOC like so:

export default function HOC(WrappedComponent) {
  return class extends Component {

    static propTypes = {
      i: PropTypes.number.isRequired
    };

    render() {
console.log(this.props);
      return <WrappedComponent
        {...this.props}/>;
    }
  };
}

And my wrapped component is like so:

WrappedComponent extends Component {
    static defaultProps = {
      i: 0
    };

    render() {
      return <div/>;
    }
  };

export default HOC(WrappedComponent);

In my console.log in the HOC, i is not defined. The props passed into WrappedComponent by its parent are, however, defined in the HOC. How can I solve this issue?

Upvotes: 0

Views: 2221

Answers (1)

YUzhva
YUzhva

Reputation: 333

That is example based on official React Higher-order Components documentation:

class HOC extends React.Component {
  render() {
    return (<p>{this.props.defaultPropAsExtreFeature}</p>);
  }
};

function createHOCWithExtraFeatures(WrappedComponent) {
  return class extends React.Component {
    static defaultProps = {
      defaultPropAsExtreFeature: "You will be able to see me at HOC"
    };
    
    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
}

const ExtendedHoc = createHOCWithExtraFeatures(HOC);

ReactDOM.render(
  <ExtendedHoc />,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Option #2

You could create React.Component and than just extend it like:

class HOC extends React.Component {
  static defaultProps = {
    HOCDefaultValue: 'You will be able to see me as WrappedComponent property',
  };

  render() {
    return (<p>1</p>);
  }
};

// NOTE: WrappedComponent doesn't have any properties
// it inherit them from HOC
class WrappedComponent extends HOC {
  render() {
    return (<p>{this.props.HOCDefaultValue}</p>);
  }
}

ReactDOM.render(
  <WrappedComponent />,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

The benefit of the 1st method is that everytime you are using createHOCWithExtraFeatures you are creating a new component and you could assign it to some const.

Upvotes: 1

Related Questions