9

When creating an HOC I'm not sure which kind of component will be wrapped, sometimes it is another React Component, sometimes it could be a plain DOM Element as li and a.

WrappedComp = myHOC(BaseComponent)

MyHOC will pass extra props to the wrapped component and in most of the cases this will work as it should.

But sometimes when BaseComponent is for example an li it will not accept the extra props and React will throw a warning Unkown Prop Warning saying that DOM element do not accept non-standard dom attributes: https://facebook.github.io/react/warnings/unknown-prop.html

So how could I check if BaseComponent is a DOM element or else? In case it is I will not pass the extra props to it.

Is there a better way to do this?

7
  • Did you check the output of console.log(BaseComponent) ? Commented Apr 12, 2017 at 10:29
  • Why do you need to wrap the HOC over every component? Is it possible to wrap and export the components which you want to extend with it? Commented Apr 12, 2017 at 10:41
  • 1
    Easiest check is to see if its a function, typeof(BaseComponent) == "function", as for HTML components, react uses a string. Commented Apr 12, 2017 at 10:42
  • 1
    This check alone won't solve the issue though as React will give you these warnings over any component which has propTypes defined. Commented Apr 12, 2017 at 10:44
  • 1
    related: stackoverflow.com/questions/33199959/… Commented Apr 12, 2017 at 14:46

2 Answers 2

10

Short answer:
Check if element is of type string to check if element is a DOM element.
Check if element is of type function to check if element is a React component.

Example:

  if (typeof BaseComponent.type === 'string') {
    return BaseComponent
  }
  // add props

Long answer:
As defined in the React documentation, built-in components like <li> or <span> results in a string 'li' or 'span' being passed to React.createElement, e.g. React.createElement("li").
Types that start with a capital letter like <Foo /> compile to React.createElement(Foo) and correspond to a component defined or imported in your JavaScript file.

Consequently, a React Component is of type function, while a DOM Component is of type string.

The following WrapperComponent logs the typeof child.type of each child element. The output is function, string, string.

function WrappedComponent({children}) {
  return React.Children.map(children, child => {
    console.log(typeof child.type)
    ...
  })
}

const BaseComponent = ({children}) => children

function App() {
  return (
    <WrappedComponent>
      <BaseComponent>This element has type of function🔥</BaseComponent>
      <span>This element has type of string</span>
      <li>This element has type of string</li>
    </WrappedComponent>
  )
}
Sign up to request clarification or add additional context in comments.

1 Comment

I believe this is the correct answer
4

Check if BaseComponent is a React Component, and add the required props.

if(BaseComponent.prototype.isReactComponent){
    //add props
}

3 Comments

Any doc about this?
github.com/facebook/react/blob/… you can see it in the source code.
I guess internal functions not documented shouldn't be used because they could change anytime. Also this wouldn't work if using pure render functions

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.