适用于es6 (弱) Maps、Sets的正确React组件PropTypes

25
我希望通过PropTypes强制用户传递一个ES6 Map对象给React组件,例如像这样:

es6 Map object

static propTypes = {
  elementsMap: React.PropTypes.map(React.PropTypes.string, editorPropTypes.element).isRequired,
}

但看起来在React中没有类似的东西。(官方文档)。

3个回答

32
elementsMap: p.instanceOf(Map).isRequired

4
那么集合元素的类型呢? 就像我们可以使用数组属性arrayProp: PropTypes.arrayOf(PropType.string)那样。 - Oleh
4
'p'是什么?是指PropTypes主模块吗? - Eliran Malka
在这种情况下,p确实是PropTypes的主模块,instanceOf是一个可以从prop-types导入的对象。因此,您可以简单地导入它import { instanceOf } from 'prop-types';然后将其用作propTypes:elementsMap: instanceOf(Map).isRequired - Анна

6

虽然不太方便,但是编写自己的 PropType 是可能的。

来自 React 的源代码(目前不幸没有暴露出来):

function createChainableTypeChecker(validate) {
  function checkType(isRequired, props, propName, componentName, location, propFullName) {
    componentName = componentName || ANONYMOUS;
    propFullName = propFullName || propName;
    if (props[propName] == null) {
      var locationName = ReactPropTypeLocationNames[location];
      if (isRequired) {
        return new Error('Required ' + locationName + ' `' + propFullName + '` was not specified in ' + ('`' + componentName + '`.'));
      }
      return null;
    } else {
      return validate(props, propName, componentName, location, propFullName);
    }
  }

  var chainedCheckType = checkType.bind(null, false);
  chainedCheckType.isRequired = checkType.bind(null, true);

  return chainedCheckType;
}

你可以像这样使用它:

const map = createChainableTypeChecker(function(props, propName, componentName, location, propFullName) {
    if (...) {
        return null; // pass the check
    }
    return new Error('Error message'); // fail the check
});

2

尝试使用自定义属性验证函数(来源于文档):

// You can also specify a custom validator. It should return an Error
// object if the validation fails. Don't `console.warn` or throw, as this
// won't work inside `oneOfType`.
customProp: function(props, propName, componentName) {
  if (!/matchme/.test(props[propName])) {
    return new Error('Validation failed!');
  }
}

那可能看起来像这样:

因此,它可能看起来像:

static propTypes = {
    elementMap: (props, propName) => {
        const m = props[propName];
        if (!m) { return new Error(`Required property ${propName} not supplied`); }
        if (!(m instanceof Map)) { return new Error("must be a Map"); }
        // check contents of map if you want...
    },
};

我该如何指定一个包含这个proptype的数组,或者一个PropTypes.Shape呢? - Vitali Zaidman
将该函数存储为变量(例如MyPropTypes.mapRequired),并在需要使用任何其他prop类型(如PropType.string)的地方使用MyPropTypes.mapRequired - Brandon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接