反应HoC PropTypes / PascalCase

时间:2018-10-09 16:24:36

标签: reactjs higher-order-components

在React中,我试图将一个组件作为道具传递给另一个组件(HoC)。但是当我尝试在其中使用该组件时,出现两个错误,并且该组件将无法呈现。

以下是错误:

“警告:propTypes被定义为Gridlist上的实例属性。请使用静态属性来定义propTypes。”

“警告:使用不正确的大小写。对React组件使用PascalCase,对于HTML元素使用小写字母。”

代码如下:

import React, {Component} from 'react'
import ActivityCard from '../activities-card/activities-card'
import Gridlist from '../grid-list/grid-list'
import PropTypes from 'prop-types'

export default class ActivitiesGrid extends Component {
  propTypes = {
    items: PropTypes.array,
    cellHeight: PropTypes.number,
    columns: PropTypes.number
  }
  render () {
    return (
      <Gridlist
        items={this.props.items}
        cardComponent={<ActivityCard />}
        cellHeight={this.props.cellHeight}
        columns={this.props.columns}/>
    )
  }
}

import ActivityCard from '../activities-card/activities-card'
import GridListTile from '@material-ui/core/GridListTile'
import MaterialGridList from '@material-ui/core/GridList'
import PropTypes from 'prop-types'
import React from 'react'

export default class Gridlist extends React.Component {
  propTypes = {
    items: PropTypes.array,
    cellHeight: PropTypes.number,
    columns: PropTypes.number,
    image: PropTypes.string,
    cardComponent: PropTypes.instanceOf(ActivityCard)
  }
  render () {
    return (
      <MaterialGridList cellHeight={this.props.cellHeight} cols={this.props.columns}>
        {this.props.items.map(item => (
          <GridListTile cols={1} key={item.key}>
            <cardComponent content={item} />
          </GridListTile>
        )
        )}
      </MaterialGridList>
    )
  }
}

import Button from 'glamorous'
import Card from '@material-ui/core/Card'
import CardActions from '@material-ui/core/CardActions'
import CardContent from '@material-ui/core/CardContent'
import PropTypes from 'prop-types'
import React from 'react'
import Typography from '@material-ui/core/Typography'

export default class ActivityCard extends React.Component {
  propTypes = {
    content: PropTypes.object
  }
  render () {
    return (
      <Card>
        <CardContent>
          <img src={this.props.content.imageUri} />
          <Typography>{this.props.content.title}</Typography>
        </CardContent>
        <CardActions>
          <Button>Points</Button>
        </CardActions>
      </Card>
    )
  }
}

1 个答案:

答案 0 :(得分:0)

您需要将propTypes定义为静态属性,因此应该为

static propTypes = {
}

静态属性仍然是第2阶段的建议(info),因此您需要使用Babel插件来转换语法。 transform-class-properties插件将为您处理此语法。

很明显,如果您不想使用babel插件,则可以只在类上定义属性。本质上,这就是插件会将您的代码转换成的形式。

export default class ActivityCard extends React.Component {
  ...
}

ActivityCard.propTypes = {
  items: PropTypes.array,
  cellHeight: PropTypes.number,
  columns: PropTypes.number
}

react文档实际上在defaultProps的文档中对此进行了解释,但是原理是相同的。

https://reactjs.org/docs/typechecking-with-proptypes.html#default-prop-values

  

如果您使用的是Babel变换(如transform-class-properties),则还可以在React组件类中将defaultProps声明为静态属性。但是,该语法尚未最终确定,需要编译步骤才能在浏览器中工作。有关更多信息,请参见类字段建议。

要对Pascal大小写错误进行排序,您需要执行以下操作之一

克隆元素并为其传递新的道具

{React.cloneElement(this.props.cardComponent, content={item})}

命名为Pascal大小写。 (不确定是否可以在道具本身上执行此操作)。

// store it in some variable
const CardComponent = this.props.cardComponent;

// n.b. you might not need to do this if you just pass the prop in with
// the correct casing although i'm not sure this is a sensible approach.
// I think you're saying PascalCasing the prop directly doesn't work?

<CardComponent content={item} />