【问题标题】:React proptype array with shape用形状反应proptype数组
【发布时间】:2015-11-26 08:29:19
【问题描述】:

是否有一种内置的方式使用 proptypes 来确保传递给组件的对象数组实际上是特定形状的对象数组?

也许是这样的?

annotationRanges: PropTypes.array(PropTypes.shape({
    start: PropTypes.number.isRequired,
    end: PropTypes.number.isRequired,
})),

我在这里遗漏了一些非常明显的东西吗?看来这会很受追捧。

【问题讨论】:

    标签: arrays reactjs react-proptypes


    【解决方案1】:

    您可以使用React.PropTypes.shape() 作为React.PropTypes.arrayOf() 的参数:

    // an array of a particular shape.
    ReactComponent.propTypes = {
       arrayWithShape: React.PropTypes.arrayOf(React.PropTypes.shape({
         color: React.PropTypes.string.isRequired,
         fontSize: React.PropTypes.number.isRequired,
       })).isRequired,
    }
    

    请参阅文档的Prop Validation 部分。

    更新

    截至react v15.5,不推荐使用React.PropTypes,而应使用独立包prop-types

    // an array of a particular shape.
    import PropTypes from 'prop-types'; // ES6 
    var PropTypes = require('prop-types'); // ES5 with npm
    ReactComponent.propTypes = {
       arrayWithShape: PropTypes.arrayOf(PropTypes.shape({
         color: PropTypes.string.isRequired,
         fontSize: PropTypes.number.isRequired,
       })).isRequired,
    }
    

    【讨论】:

    • 值得指出.isRequiredReact.PropTypes.shape 的每个属性上的使用。我来到这里是因为我错误地认为通过在React.PropTypes.arrayOf 上使用.isRequired,我不需要它。为了实现全覆盖验证,我实际上最终也将其直接应用于React.PropTypes.shape
    • 是的,我做的事情和你完全一样,但是有可能只根据需要标记你想要的键。顺便说一句,对我来说,显式总是比隐式好。
    • 这个例子对我来说没有正确验证失败。如果 if arrayWithShape 是 [] (一个空数组)它不会失败。如果 arrayWithShape 是 {} (一个对象),它确实会失败。如果 arrayWithShape[{dumb: 'something'}] (一个没有正确道具的数组)它会失败。如果arrayWithShape 是一个空数组,我需要它验证失败。我只希望它是一个非空数组,其对象具有 colorfontsize。我错过了什么?
    • 值得注意的是,您也可以将这些作为命名导入导入。即import { shape } from 'prop-types';
    【解决方案2】:

    是的,你需要在代码中使用PropTypes.arrayOf而不是PropTypes.array,你可以这样做:

    import PropTypes from 'prop-types';
    
    MyComponent.propTypes = {
      annotationRanges: PropTypes.arrayOf(
        PropTypes.shape({
          start: PropTypes.string.isRequired,
          end: PropTypes.number.isRequired
        }).isRequired
      ).isRequired
    }
    

    有关 proptypes 的更多详细信息,请访问 Typechecking With PropTypes here

    【讨论】:

    • PropTypes.shape 对象中添加 .isRequired 的原因是什么?
    • @makovkastar 因为没有它,[undefined] 将通过验证
    【解决方案3】:

    它就在我的鼻子底下:

    来自 react 文档本身:https://facebook.github.io/react/docs/reusable-components.html

    // An array of a certain type
        optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
    

    【讨论】:

      【解决方案4】:

      有一个 ES6 速记导入,你可以参考。更具可读性和易于输入。

      import React, { Component } from 'react';
      import { arrayOf, shape, number } from 'prop-types';
      
      class ExampleComponent extends Component {
        static propTypes = {
          annotationRanges: arrayOf(shape({
            start: number,
            end: number,
          })).isRequired,
        }
      
        static defaultProps = {
           annotationRanges: [],
        }
      }
      

      【讨论】:

      • 请查看How do I write a good answer。不鼓励仅使用代码的答案,因为它们没有解释如何解决问题中的问题。您应该更新您的答案,以解释它的作用以及它如何改进该问题已有的投票答案。
      【解决方案5】:

      如果我要为特定形状多次定义相同的 proptypes,我喜欢将其抽象到一个 proptypes 文件中,这样如果对象的形状发生变化,我只需在一个地方更改代码。它有助于使代码库干涸一点。

      例子:

      // Inside my proptypes.js file
      import PT from 'prop-types';
      
      export const product = {
        id: PT.number.isRequired,
        title: PT.string.isRequired,
        sku: PT.string.isRequired,
        description: PT.string.isRequired,
      };
      
      
      // Inside my component file
      import PT from 'prop-types';
      import { product } from './proptypes;
      
      
      List.propTypes = {
        productList: PT.arrayOf(product)
      }
      

      【讨论】:

        【解决方案6】:

        这也是我防止空数组的解决方案:

        import React, { Component } from 'react';
        import { arrayOf, shape, string, number } from 'prop-types';
        
        ReactComponent.propTypes = {
          arrayWithShape: (props, propName, componentName) => {
            const arrayWithShape = props[propName]
            PropTypes.checkPropTypes({ arrayWithShape:
                arrayOf(
                  shape({
                    color: string.isRequired,
                    fontSize: number.isRequired,
                  }).isRequired
              ).isRequired
            }, {arrayWithShape}, 'prop', componentName);
            if(arrayWithShape.length < 1){
              return new Error(`${propName} is empty`)
            }
          }
        }
        

        【讨论】:

          猜你喜欢
          • 2020-01-19
          • 1970-01-01
          • 2021-06-19
          • 2019-03-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多