简体   繁体   English

如何在React v16中手动调用自定义PropType验证器

[英]How to manually call custom PropType validators in React v16

I have a use case where I need to write a custom React PropType validator. 我有一个用例,我需要编写一个自定义的React PropType验证器。 Within that checker I want to do two things: 1) validate that the prop names inside the object, which are dynamically generated, are all md5 hashes, and 2) validate the "shape" of the object connected to each prop. 在该检查器中,我想做两件事:1)验证对象内部的道具名称(它们是动态生成的)都是md5哈希值,以及2)验证连接到每个道具的对象的“形状”。

Question #1 I have figured out; 问题#1我已经知道了; #2 is eluding me a bit. #2让我有些迷惑。 Here's some code to illustrate: 这是一些代码说明:

Say I have an object like this: 说我有一个这样的对象:

{
  key1: {
    byHash: {
      '<some md5 hash>': { ... }
    }
  },
  key2: {
    byHash: {
      '<some md5 ash>': { ... }
    }
  }
}

When checking this object I want to make sure that the keys are indeed md5 hashes, and then I want to ensure the correctness of the keys and their values in each of the objects assigned to key1 and key2 . 在检查该对象时,我想确保键确实是md5哈希,然后我要确保分配给key1key2每个对象中键及其值的正确性。 Let's say, in addition, I've created a validator function like so: 可以说,此外,我还创建了一个验证器函数,如下所示:

const validObjShape = PropTypes.shape({
  someString: PropTypes.string.isRequired,
  someBoolean: PropTypes.bool
});

Then I write my custom validator function: 然后,编写我的自定义验证器函数:

const validCustomProp  = (props, propName, componentName) => {
  const obj = props[propName];

  if (!isObject(obj)) {
    return new Error(
      //eslint-disable-next-line
      'Invalid prop `' + propName + '`of type `' + typeof obj + '` supplied to ' +
      '`' + componentName + '`, expected an object.'
    );
  }

  if (isEmpty(obj)) {
    return null;
  }

  forEach(obj, (v, k) => {
    const isMD5 = (/[a-fA-F0-9]{32}/).test(k);

    if (!isMD5) {
      throw new Error(
        //eslint-disable-next-line
        'Invalid dynamic key on `' + propName + '`. All keys ' +
        'on this object should be md5 hashes, but we found `' + k + '` instead.'
      );
    }
  });

  // Here I want to somehow validate each object on `obj`. Something like:
  // forEach(obj, (v, k) => { 
  //   const err = validObjShape(props[propName], k, componentName);
  //   if (err) {
  //     // throw some err...
  //   }
  // }

  return null;
};

My question -- as noted in-line above -- can I use the validObjShape that I created above to validate the shape of the objects nested within obj . 我的问题(如上所述)可以使用上面创建的validObjShape来验证嵌套在obj中的对象的形状。 I think that this calling of a validator fn directly will be disallowed in v16 of React (see this post ). 我认为在React v16中将不允许直接调用验证器fn(请参阅本文 )。 So how can this now be achieved? 那么现在如何实现呢?

Using PropTypes directly from React is deprecated - not the use of PropTypes themselves. PropTypes 从React直接使用PropTypes不使用PropTypes本身。

As it says in the docs, declaring PropTypes is fine , just use the prop-types library instead. 就像在文档中说的那样, 声明PropTypes很好 ,只需使用prop-types库即可。

So, 所以,

const apiShape = React.PropTypes.shape({
  body: customValidator,
  statusCode: React.PropTypes.number.isRequired
}).isRequired;

simply changes to 只需更改为

import PropTypes from 'prop-types';
const apiShape = React.PropTypes.shape({
  body: customValidator,
  statusCode: PropTypes.number.isRequired
}).isRequired;

And the customValidator doesn't have to change. 而且customValidator不必更改。

You can verify this yourself in the source: ElementCreation => ElementValidation in DEV mode => Validating prop types => calling checkPropTypes which has simply been moved here 您可以在源代码中对此进行验证: ElementCreation => DEV模式下的ElementValidation => 验证道具类型 => 调用仅在此处移动的checkPropTypes

React strongly believes in type safety and deprecating PropTypes altogether seems very unlikely. React坚信类型安全性,并且完全不赞成使用PropTypes似乎不太可能。 It is still present in the docs (from the master) 它仍然存在于文档中(来自母版)

Calling validator functions as you mentioned is now deprecated too 如前所述,调用验证函数也已被弃用

Note from the docs 来自文档的注释

This is new behavior, and you will only encounter it when you migrate from React.PropTypes to the prop-types package. 这是新行为,只有在从React.PropTypes迁移到prop-types包时才会遇到它。

So the following is deprecated 所以不推荐使用以下内容

  Object.keys(props[propName]).forEach(k => {

    // const v = props[propName][k];
    const isMD5 = (/[a-fA-F0-9]{32}/).test(k);
    if (!isMD5) {
      return new Error(
        'Not an md5'
      );
    }

    return validObjShape(props[propName], k, componentName);
  });

Instead use checkPropTypes : 而是使用checkPropTypes

const validObjShape = PropTypes.shape({
  someString: PropTypes.string.isRequired,
  someBoolean: PropTypes.bool
});

const validCustomProp  = (props, propName, componentName) => {

  Object.keys(props[propName]).forEach(k => {

    const v = props[propName][k];
    const isMD5 = (/[a-fA-F0-9]{32}/).test(k);
    if (!isMD5) {
      return new Error(
        'Not an md5'
      );
    }

    PropTypes.checkPropTypes({ [k]: validObjShape }, { [k]: v }, propName, componentName);

  });


  return null;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM