【问题标题】:React Prop Types Different Required Props Depending on Flag根据标志反应道具类型不同的必需道具
【发布时间】:2018-05-03 11:07:10
【问题描述】:

我有一个 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] 之一。

在我的组件中

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

问题是,有没有办法做到这一点?

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

【问题讨论】:

标签: reactjs react-proptypes


【解决方案1】:

您可以使用自定义 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}.`
            );
        }
    }
}

【讨论】:

  • ? 谢谢,这确实是要走的路,但是已经有一个 npm 包可以解决这个问题,正如 cmets 中所建议的那样,所以我已经发布了我自己的答案和一个可行的解决方案使用它。
【解决方案2】:

正如wgcrouch 在他的回答中所建议的那样,prop-types 库不提供此功能,因此使用自定义道具类型是可行的方法。

幸运的是,正如 Tom Fenech 在 cmets 中对我的问题所指出的那样,这个特殊问题已经解决了,所以我使用了一个可用的 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

【讨论】:

    猜你喜欢
    • 2017-09-26
    • 2017-04-07
    • 1970-01-01
    • 2018-06-14
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    相关资源
    最近更新 更多