高阶组件的PropTypes

时间:2016-06-15 23:48:19

标签: javascript reactjs

对于来自高阶组件内部组件的PropTypes,是否有办法指向它们的创建位置?

enter image description here

这是一个很小的示例,但如果整个应用程序中有多个EnhancedButtons在单独的文件中,则调试起来非常困难。

由于高阶组件理想地用于可重用性,我们可能永远不会知道缺少handleClick方法的组件的位置。 _EnhancedButton的呈现方法是我们想要增强的任何Component的变量。

有没有办法让PropTypes在创建它们的地方更加明显,例如插入FinalButton并且是_EnhancedButton的实例并且缺少prop handleClick?

https://jsfiddle.net/kriscoulson/sh2b8vys/3/

var Button = (props) => (
	<button onClick={ () => props.handleClick() }>
		Submit
	</button>
);

Button.propTypes = {
	handleClick: React.PropTypes.func.isRequired
}

const EnhanceButton = Component => class _EnhancedButton extends React.Component {
	render () {
  	return (<Component { ...this.props }>{this.props.children}</Component>);
  }
}

const FinalButton = EnhanceButton(Button);

ReactDOM.render(
  <FinalButton />,
  document.getElementById('container')
);
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>

<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

2 个答案:

答案 0 :(得分:21)

您的示例中的名称FinalButton无法做出反应,因为这只是您的本地变量名称,但我们将生成的组件的名称更改为您想要的任何名称。我在这里使用&#34; Final&#34;在原来的名字前面。

此外,我们可以将道具类型复制/合并到新元素。

function EnhanceButton(Component) {
    class _EnhancedButton extends React.Component {
        static displayName = 'Final' + (Component.displayName || Component.name || 'Component');

        render() {
            return (
                <Component { ...this.props }>{this.props.children}</Component>
            );
        }
    }
    _EnhancedButton.propTypes = Component.propTypes;

    return _EnhancedButton;
}

这给出:警告:propType失败:handleClick中未指定必需的道具Button。检查FinalButton的呈现方法。

小提琴:https://jsfiddle.net/luggage66/qawhfLqb/

答案 1 :(得分:6)

虽然Luggage的答案非常有效,但另一种可能更清洁的替代方法是将你的proptypes声明为静态并将其声明在组件的主体内部。

const EnhanceButton = Component => class extends React.Component {
  static propTypes = {
    children: PropTypes.node,
  }
  static defaultProps = {
    children: false,
  }
    render () {
    return (
      <Component 
        { ...this.props }
      >
        {this.props.children}
      </Component>
    );
  }
}