尽管在 defaultProps 中设置了 children 道具,但为什么它仍未定义?
Why is children prop undefined, despite setting it in defaultProps?
我想为我的 React 组件设置 PropTypes 验证,以便在没有子组件时发出警告。但是当我遵循 PropTypes 语法 recommended by the React docs 时,我抛出了这个错误:
prop type children
is invalid; it must be a function, usually from the prop-types
package, but received undefined
.
当我在 Chrome 调试器中单步执行时,我看到 children
在执行验证时是 undefined
。但是我特意在defaultProps
里设置了children
,为什么是undefined
呢?我为 defaultProps.children
尝试了几个不同的值,包括 []
和 ''
。他们都产生了同样的错误。
请注意,我的应用运行正常。只有 PropTypes
验证失败。
下面是有问题的代码的简化版本。请注意,我使用静态属性来定义 defaultProps
(如 recommended by Dan Abramaov)。我正在使用 create-react-app
所以我有 Babel 转换来启用默认的 class 属性语法。
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>
);
}
}
错误消息有点混乱,但它指的是 children
的 prop-type 声明(即 PropTypes.node.required
),这是 undefined
因为打字错误.应该是 PropTypes.node.isRequired
.
我想为我的 React 组件设置 PropTypes 验证,以便在没有子组件时发出警告。但是当我遵循 PropTypes 语法 recommended by the React docs 时,我抛出了这个错误:
prop type
children
is invalid; it must be a function, usually from theprop-types
package, but receivedundefined
.
当我在 Chrome 调试器中单步执行时,我看到 children
在执行验证时是 undefined
。但是我特意在defaultProps
里设置了children
,为什么是undefined
呢?我为 defaultProps.children
尝试了几个不同的值,包括 []
和 ''
。他们都产生了同样的错误。
请注意,我的应用运行正常。只有 PropTypes
验证失败。
下面是有问题的代码的简化版本。请注意,我使用静态属性来定义 defaultProps
(如 recommended by Dan Abramaov)。我正在使用 create-react-app
所以我有 Babel 转换来启用默认的 class 属性语法。
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>
);
}
}
错误消息有点混乱,但它指的是 children
的 prop-type 声明(即 PropTypes.node.required
),这是 undefined
因为打字错误.应该是 PropTypes.node.isRequired
.