如何为高阶功能组件设置 PropTypes?

Posted

技术标签:

【中文标题】如何为高阶功能组件设置 PropTypes?【英文标题】:How do I set PropTypes for Higher Order Functional Component? 【发布时间】:2018-04-08 19:25:18 【问题描述】:

我正在为 eslint 使用 airbnb 配置,它给了我这个警告:

[eslint] 'isLoading' is missing in props validation (react/prop-types)

有没有办法为 isLoading 设置 PropTypes?

const withLoading = Component => ( isLoading, ...rest ) =>
  (isLoading ? <LoadingSpinner /> : <Component ...rest />);

以下是我如何使用它的示例:

const Button = ( onClick, className, children ) => (
  <button onClick=onClick className=className type="button">
    children
  </button>
);
Button.propTypes = 
  onClick: PropTypes.func.isRequired,
  className: PropTypes.string,
  children: PropTypes.node.isRequired,
;
Button.defaultProps = 
  onClick: () => ,
  className: '',
  children: 'Click me',
;

const Loading = () => (
  <div>
    <p>Loading...</p>
  </div>
);

const withLoading = Component => ( isLoading, ...rest ) =>
  (isLoading ? <Loading /> : <Component ...rest />);

// How do I set propTypes for isLoading?
// I tried this but it didn't work:
// withLoading.propTypes = 
// isLoading: PropTypes.bool
// ;

const ButtonWithLoading = withLoading(Button);

// The rendered component is based on this boolean.
// isLoading === false:  <Button /> is rendered
// isLoading === true:   <Loading /> is rendered
const isLoading = false;

ReactDOM.render(
  <ButtonWithLoading
      isLoading=isLoading 
      onClick=() => alert('hi')
  >Click Me</ButtonWithLoading>,
  document.getElementById('root')
);

我也将它发布到 jsfiddle:http://jsfiddle.net/BernieLee/5kn2xa1j/36/

【问题讨论】:

是的,只需设置withLoading.propTypes = isLoading: PropTypes.bool ;。我认为是***.com/questions/37847616/… 的副本 感谢您的回复,Larce。我试过了,但我认为它不起作用,因为isLoadingComponent 的道具中,而不是withLoading。请参阅下面我对 Chamidu 的回复。 【参考方案1】:

这是你需要的:

const withLoading = (Component) => 
  const wrapped = ( isLoading, ...rest ) => (
    isLoading ? <div>Loading</div> : <Component ...rest />
  );
  wrapped.propTypes = 
    isLoading: PropTypes.bool.isRequired,
  ;
  return wrapped;
;
withLoading.propTypes = 
  Component: PropTypes.element,
;

【讨论】:

太棒了!谢谢,@MaelFr 如果你使用eslint-plugin-react-hooks,并且如果你打算在你的内部组件中使用钩子,你需要用大写W命名你的内部函数式反应组件Wrapped,否则eslint将抛出错误react-hooks/rules-of-hooks【参考方案2】:

猜测 isLoading 是一个布尔值

withLoading.propTypes = 
    isLoading: React.PropTypes.bool
;

【讨论】:

你说得对,Chamedu,我应该说 isLoading 是一个布尔值但是 isLoading 是在被包装的 Component 的 props 中,而不是 withLoading。我试过这个:Component.propTypes = isLoading: PropTypes.bool, ; 如果我尝试这个,我会收到这个警告:[eslint] 'Component' is not defined. (no-undef) 'Component' 是传入要包装的任何组件的占位符名称。 您能否在此处添加更多代码。您如何使用“withLoading”组件。也许一些 JSX 可能你必须将 propTypes 添加到包装的组件中。但是没有看到实现我不能给你更准确的答案 移除“Component =>”部分并检查它是否工作。

以上是关于如何为高阶功能组件设置 PropTypes?的主要内容,如果未能解决你的问题,请参考以下文章

如何为BEM块设置外部几何图形或定位?

如何为 Discord 网关设置心跳功能

高阶组件中功能组件的道具

如何为可移动的浮动按钮设置 onTouch 和 onClick 功能

如何为单选按钮和复选框设置禁用/只读功能

React: 高阶组件(HOC)