Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct PropTypes for component or element

Tags:

reactjs

I am creating a component that I want the element type to be configurable.

const Col = ({ containerElement, children }) => {
  return (
    <containerElement>
      {children}
    </containerElement>
  );
};

Col.defaultProps = {
  containerElement: 'div'
};

So container element could either be as in the defaultProps above or it could be a component.

<Col containerElement={<MyComponent} />

I can't get the propTypes to validate, I have tried this:

Col.propTypes = {
  className: PropTypes.string,
  containerElement: PropTypes.oneOf([
    PropTypes.string,
    PropTypes.element
  ]),

But it does not validate correctly.

Warning: Failed propType: Invalid prop componentClass of value div supplied to Col,

like image 342
dagda1 Avatar asked Oct 27 '25 10:10

dagda1


2 Answers

Now with prop-types 15.7.0 released you can do:

Col.propTypes = {
  ...
  containerElement: PropTypes.elementType,
}
like image 161
Elad Levy Avatar answered Oct 29 '25 00:10

Elad Levy


There is some wrong stuffs in your code:

you put a non-capitalize react component (which exists in the element's props):

const Col = ({ containerElement, children }) => {
  return (
    <containerElement>    // <---this should start with uppercase letter
      {children}
    </containerElement>
  );
};

Col.defaultProps = {
  containerElement: 'div' // this should be Componenet type not string
};

React Components always should start with capital letter else it will be conflicted with html elements

Col.propTypes = {
  className: PropTypes.string,
  containerElement: PropTypes.oneOf([ // you should use PropTypes.oneOfType
    PropTypes.string,
    PropTypes.element
  ])

PropTypes.oneOf is used to indicate that the value should be in the array argument.

PropTypes.oneOfType is used to indicate that the value's type shoudl be in the array argument.

if we say Component.propTypes = { theme: PropTypes.oneOf(["dark", "light"])} we indicate that the value of theme props should be either dark or light.

if we say Component.propTypes = { data: PropTypes.oneOfType([PropTypes.string, PropTypes.number])} we indicate that type of the data prop should be string or number.

before i show you a demo code that i wrote you should know the difference between component and component element. if you know so you can skip this part:

component is: Component and it's type is PropTypes.elementType. component element is <Componenet /> or <Component>...</Component> and it's type is PropTypes.element.

*here is my demo code if you have any propblem or didn't understand it, feel

free to ask:*
import { oneOfType, string, element, elementType } from 'prop-types';
import { Fragment } from 'react';

// defining test component
function Test({ Element, ElementType }) {
  console.log(ElementType)
  return (
    <ElementType> {/* <--- [*] Note React Component Should be capitalized */}
      Here is Element : {Element}
    </ElementType>
  )
}
// default props for Test
Test.defaultProps = {
  Element: <u>default element</u>,
  ElementType: Fragment

}

// define propTypes for Test
Test.propTypes = {
  Element: oneOfType([string, element]), // <-- you should use oneOfType not oneOf
  ElementType: elementType
}

// define Wrapper component
function Wrapper({ children }) {
  return (
    <div style={{ backgroundColor: "lightgreen" }}>
      {children}
    </div>
  )
}



export default function App() {
  return (
    <>
      <Test />
      <hr />
      <Test ElementType={Wrapper} />
      <hr />
      <Test Element="hi i am element prop (string type)" />
      <hr />
      <Test Element={<b>hi another time (element type)</b>} ElementType={Wrapper} />
    </>

  )
}
like image 39
0MR4N Avatar answered Oct 29 '25 00:10

0MR4N