代码之家  ›  专栏  ›  技术社区  ›  Patrick Hund

反应道具类型根据标志不同需要不同道具

  •  2
  • Patrick Hund  · 技术社区  · 7 年前

    我有一个React组件,它获取一个配置对象作为道具,它看起来像这样:

    {
        active: true,
        foo: {
             bar: 'baz'
        }
    }
    

    在某些情况下,我希望通过传入不同的对象来禁用组件显示的功能 active: false ,如下所示:

    {
        active: false
    }
    

    这很好,不是问题所在。

    但是,我还想确保使用我的组件的客户端代码提供了正确的配置对象:

    • 如果active为true,则需要foo
    • 如果active为false,则foo是可选的,不需要提供

    我如何为这样的情况定义道具类型?

    我试过:

    MyComponent.propTypes = {
        config: PropTypes.oneOf([
            {
                active: false
            },
            PropTypes.shape({
                active: true,
                foo: PropTypes.shape({
                    bar: PropTypes.string.isRequired
                })
            }).isRequired
        ]).isRequired
    };
    

    但这给了我以下警告:

    警告:失败的属性类型:无效的属性 config 有价值的 [object Object] 提供给 MyComponent ,应为[{“active”:true},null]之一。

    在MyComponent中

    我知道为什么这不起作用:因为 PropTypes.oneOf 不期望动态属性类型匹配器作为值,而只是一个有效参数数组。

    问题是,有没有办法让这一切奏效?

    我制作了一个可运行的沙盒示例,您可以在其中试用上面的示例代码: https://codesandbox.io/s/n9o0wl5zlj

    2 回复  |  直到 4 年前
        1
  •  5
  •   Patrick Hund    7 年前

    wgcrouch 在他的回答中提出 prop-types lib不提供此功能,因此使用自定义道具类型是可行的。

    幸运的是,正如Tom Fenech在对我的问题的评论中指出的那样,这个特定的问题已经解决了,因此我使用了一个npm包: react-required-if .

    我的工作解决方案如下所示:

    import React from 'react';
    import PropTypes from 'prop-types';
    import requiredIf from 'react-required-if';
    
    function MyComponent({ config }) {
      if (!config.active) {
        return null;
      }
      return <h1>Hello {config.foo.bar}!</h1>;
    }
    
    MyComponent.propTypes = {
      config: PropTypes.shape({
        active: PropTypes.bool.isRequired,
        foo: requiredIf(
          PropTypes.shape({
            bar: PropTypes.string.isRequired
          }),
          props => props.active
        )
      })
    };
    
    export default MyComponent;
    

    看见 updated code sandbox with solution .

        2
  •  4
  •   TallOrderDev WayneC    4 年前

    您可以使用自定义的propType(记录在propTypes网站上)功能,例如:

    MyComponent.proptypes = {
        active: PropTypes.bool,
        foo: function(props, propName, componentName) {
            if (props['active'] && !props[propName]) {
                return new Error(
                    `${propName} is required when active is true in ${componentName}.`
                );
            }
        }
    }