尽管在defaultProps中设置了子项,为什么未定义子项?

时间:2018-04-08 19:33:13

标签: reactjs ecmascript-6 react-proptypes

我想为我的React组件设置PropTypes验证,以便在没有子项时发出警告。但是,当我按照PropTypes语法recommended by the React docs时,我会抛出此错误:

  

道具类型children无效;它必须是一个函数,通常来自prop-types包,但收到undefined

当我在Chrome调试器中单步执行时,我会在执行验证时看到childrenundefined。但是我在children中专门设置了defaultProps,为什么它是undefined?我为defaultProps.children尝试了几个不同的值,包括[]''。所有这些都产生了同样的错误。

请注意,我的应用可行。它是唯一失败的PropTypes验证。

以下是有问题代码的简化版本。请注意,我使用静态属性来定义defaultProps(作为recommended by Dan Abramaov)。我使用create-react-app,因此我使用Babel变换来启用默认的类属性语法。

import React, { Fragment } from 'react';
import PropTypes from 'prop-types'
import { TabContent, TabPane, Nav, NavItem, NavLink } from 'reactstrap';
import classnames from 'classnames';

export class Tab extends React.Component {

  static propTypes = {
    name: PropTypes.string.isRequired,
    children: PropTypes.node.required,
  }

  static defaultProps = {
    name: null,
    children: ''
  }

  render () { 
    return (
      <Fragment>
        {this.props.children}
      </Fragment>
    )
  }
}

export default class TabSet extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      activeTab: 0
    };
  }

  // TODO: limit to only Tab child elements. 
  static propTypes = {
    children: PropTypes.node.required,
  }

  static defaultProps = {
    children: ''
  }

  toggle = (tab) => {
    if (this.state.activeTab !== tab) {
      this.setState({
        activeTab: tab
      });
    }
  }

  render() { 
    return (
      <Fragment>
        <Nav tabs>
          {this.props.children.map((tab,i) => 
            <NavItem key={i} style={{cursor: 'pointer'}}>
              <NavLink
                className={classnames({ active: this.state.activeTab === i })}
                onClick={() => { this.toggle(i); }}
              >
                { tab.props.name }
              </NavLink>
            </NavItem>
          )}
        </Nav>
        <TabContent activeTab={this.state.activeTab}>
          {this.props.children.map((tab,i) => 
            <TabPane key={i} tabId={i}>
              {tab}
            </TabPane>
          )}
        </TabContent>
      </Fragment>
    );
  }
}

如果重要,这里有一个简单的例子说明如何使用这些组件:

import React from 'react';
import TabSet, {Tab} from './TabSet';
import HomeTab from './HomeTab';
import FriendsTab from './FriendsTab';
import HangTimesTab from './HangTimesTab';

export default class MainContainer extends React.Component {

  render() {
    return (
      <div>
        <TabSet>
          <Tab name="Home">
            <HomeTab /> 
          </Tab>
          <Tab name="Hang Times">
            <HangTimesTab />
          </Tab>
          <Tab name="Friends">
            <FriendsTab />
          </Tab>
        </TabSet>
      </div>
    );
  }
}

1 个答案:

答案 0 :(得分:2)

错误消息有点令人困惑,但它引用了children(即PropTypes.node.required)的道具类型声明,由于拼写错误而导致undefined。它应该是PropTypes.node.isRequired

相关问题