组件或元素的正确 PropTypes 是什么

What is the correct PropTypes for component or element

提问人:dagda1 提问时间:2/19/2017 最后编辑:dagda1 更新时间:8/18/2022 访问量:8440

问:

我正在创建一个组件,我希望元素类型是可配置的。

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

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

因此,容器元素可以是上面的 defaultProps 中的元素,也可以是组件。

<Col containerElement={<MyComponent} />

我无法验证,我已经尝试过了:propTypes

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

但它不能正确验证。

警告:失败的 propType:提供给 、 的值的 prop 无效componentClassdivCol

反应JS

评论

0赞 Felix Kling 2/19/2017
你到底要传递给组件什么?如果该值确实是一个元素,则无论如何都不能使用它。 是 的句法糖。即使它是一个字符串,也会传递给 ,而不是变量。在担心验证错误之前,我会确保代码本身产生正确的结果(即正常工作)。<containerElement><containerElement>React.createElement('containerElement', ...)'containerElement'React.createElementcontainerElement
0赞 patcon 10/20/2020
同意@FelixKling。您需要通过类似 <Element> 来实例化。请参阅此问题: stackoverflow.com/a/39655113/504018const ContainerElement = containerElement.inner
0赞 Giorgi Moniava 9/20/2023
@FelixKling 小问题,这里:“即使它是一个字符串,'containerElement'也会传递给 React.createElement,而不是变量 containerElement”——通过“不是变量 containerElement”,你指的是 containerElement 应该引用的组件的构造函数,对吧?
0赞 Felix Kling 9/20/2023
@GiorgiMoniava:是的。我想我在这里混合了运行时与编译时术语。 变成 ,而不是 。因此,在转换过程中,将创建字符串文字,而不是变量,并且在运行时传递字符串值,而不是变量的值。<containerElement>React.createElement('containerElement'...)React.createElement(containerElement, ...)
0赞 Giorgi Moniava 9/20/2023
@FelixKling这似乎也与 vs 有关。<containerElement><ContainerElement>

答:

1赞 Bartek Fryzowicz 2/19/2017 #1

你没有在你的组件上定义属性 - 你的道具被调用,你应该使用:componentClasscontainerElementoneOfType

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

评论

0赞 Felix Kling 2/19/2017
虽然这是正确的,但我认为这不会解决验证问题。
0赞 dagda1 2/19/2017
那是我的错别字。使用正确的名称,它仍然无法通过验证。
1赞 Limbo 5/4/2018 #2

试试这个:

Col.propTypes = {
    className: PropTypes.string,
    containerElement: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.func
    ]),
}

因为 React 组件是全局意义上的函数,并且

typeof (class MyClass {}) // => "function"
7赞 Elad Levy 3/19/2019 #3

现在,随着 prop-types 15.7.0 的发布,您可以执行以下操作:

Col.propTypes = {
  ...
  containerElement: PropTypes.elementType,
}

评论

1赞 CodeFinity 9/22/2020
这和❓有什么区别element
3赞 thelastshadow 1/14/2021
element 用于实例 (),elementType 用于组件类 ()。<Foo />Foo
3赞 0MR4N 8/18/2022 #4

你的代码中有一些错误的东西:

你放了一个非大写的 React 组件(存在于元素的 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 组件始终应以大写字母开头,否则它将与 html 元素冲突

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

PropTypes.oneOf 用于指示值应位于数组参数中。

PropTypes.oneOfType 用于指示值的类型应位于数组参数中。

如果我们说,我们表示主题道具的值应该是深色或浅色Component.propTypes = { theme: PropTypes.oneOf(["dark", "light"])}

如果我们说,我们指示 data 属性的类型应该是字符串或数字Component.propTypes = { data: PropTypes.oneOfType([PropTypes.string, PropTypes.number])}

在我向你展示我编写的演示代码之前,你应该知道组件和组件元素之间的区别。如果你知道,你可以跳过这部分:

component 是:,它的类型是 PropTypes.elementTypecomponent 元素是 or,它的类型是 PropTypes.elementComponent<Componenet /><Component>...</Component>

*这是我的演示代码,如果您有任何道具或不理解它,请感觉

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} />
    </>

  )
}