React props - 如果另一个prop为null/empty,则在prop上设置isRequired

san*_*a-p 36 javascript wai-aria reactjs

我有一个组件<Button>.
如果组件没有this.props.children,我想将prop设置ariaLabelisRequired,否则可以是可选的.我怎么做?

ariaLabel 道具不需要:

<Button>Add to bag</Button>
Run Code Online (Sandbox Code Playgroud)

ariaLabel 必须要求道具:

<Button ariaLabel="Add to bag" icon={ favorite } />
Run Code Online (Sandbox Code Playgroud)

if this.props.childrenthis.props.ariaLabel是空的,它会抛出一个错误,说this.props.ariaLabel是的isRequired

<Button icon={ favorite } />
Run Code Online (Sandbox Code Playgroud)

propTypes:

Button.propTypes = {
    /** icon inside Button. */
    icon: React.PropTypes.object,
    /** Content inside button */
    children: React.PropTypes.node,
    /** Aria-label to screen readers */
    ariaLabel: React.PropTypes.string, /*isRequired if children is empty */
};
Run Code Online (Sandbox Code Playgroud)

谢谢

chi*_*lli 93

你不需要另一个库,'prop-types'提供了这个开箱即用的功能.请参阅https://facebook.github.io/react/docs/typechecking-with-proptypes.html

例:

import PropTypes from 'prop-types';

//.......    

ExampleComponent.propTypes = {
    showDelete: PropTypes.bool,
    handleDelete: function(props, propName, componentName) {
        if ((props['showDelete'] == true && (props[propName] == undefined || typeof(props[propName]) != 'function'))) {
            return new Error('Please provide a handleDelete function!');
        }
    },

}
Run Code Online (Sandbox Code Playgroud)

  • 这就是我想要的.我不想要另一个依赖. (3认同)
  • 太多的冗长,我认为prop-types包本身应该包括这样的东西. (3认同)
  • 鉴于`prop-types` 可以开箱即用,这显然是最好的答案。 (2认同)

Kel*_*oya 15

这可能正是您所需要的:https://github.com/thejameskyle/react-required-if

在您的情况下,您的propTypes将是:

import requiredIf from 'react-required-if';

Button.propTypes = {
    /** icon inside Button. */
    icon: React.PropTypes.object,
    /** Content inside button */
    children: React.PropTypes.node,
    /** Aria-label to screen readers */
    ariaLabel: requiredIf(React.PropTypes.string, props => !props.children), /*isRequired if children is empty */
};
Run Code Online (Sandbox Code Playgroud)

  • 这个第三方库实际上有 18 行长并且很容易理解。用这个没有什么问题。如果您不喜欢使用依赖项,只需花 15 分钟将其提取到您自己的助手或其他东西中。更好的是,如果您不喜欢使用“未经测试”的依赖项,请创建存储库的分支,添加一些测试,然后提交 PR。_让世界比你来时更美好一点。_ (3认同)
  • 为什么在这里使用第三方! (2认同)
  • 如果您长期关心您的项目,则您的包中不需要另一个未经测试的依赖项。 (2认同)
  • 这个第三方代码很棒,我只是提取了代码以创建自己的自定义函数,以避免添加依赖项 (2认同)

coc*_*nup 7

要添加到上述@chickenchilli的答案中,您可以将其抽象为一个更方便的辅助函数,如下所示:

conditionalPropType.js

export default function conditionalPropType(condition, message) {
  if(typeof condition !== 'function') throw "Wrong argument type 'condition' supplied to 'conditionalPropType'";
  return function(props, propName, componentName) {
    if (condition(props, propName, componentName)) {
      return new Error(`Invalid prop '${propName}' '${props[propName]}' supplied to '${componentName}'. ${message}`);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

MyComponent.js

import PropTypes from 'prop-types';
import conditionalPropType from './conditionalPropType';

[...]

MyComponent.propTypes = {
  conditionProp: PropTypes.bool,
  dependentProp: conditionalPropType(props => (props.condition && typeof(props.someProp) !== 'boolean'), "'dependentProp' must be boolean if 'conditionProp' is true"),
};
Run Code Online (Sandbox Code Playgroud)