首页 > 解决方案 > PropTypes:如何检查对象的枚举?

问题描述

我有一系列可能的字段:

export const fields = [
  { type: 'select', defaultValue: MAINTAIN, name: TENDENCY },
  { type: 'select', defaultValue: DISTANT_ACQUAINTANCE, name: GROUP },
  { type: 'input', defaultValue: '', name: FIRST_NAME },
  { type: 'input', defaultValue: '', name: LAST_NAME },
  { type: 'input', defaultValue: '', name: CITY },
  { type: 'input', defaultValue: '', name: COMPANY },
  { type: 'input', defaultValue: '', name: POSITION },
];

例如const FIRSTNAME = 'firstName';.

<ContactCell />我在一个组件中呈现这些字段。我尝试像这样进行 PropTypes 检查:

ContactCell.propTypes = {
  field: PropTypes.oneOf(fields).isRequired,
  handleChange: PropTypes.func.isRequired,
  value: PropTypes.string.isRequired,
};

但是当我像这样渲染一个 ContactCell 时:

const createContactCell = (props = {}) =>
  render(<ContactCell {...props} handleChange={() => {}} />);

const props = {
  value: 'Mike',
  field: { type: 'input', defaultValue: '', name: 'firstName' },
};
createContactCell(props);

我得到错误:

Warning: Failed prop type: Invalid prop `field` of value `[object Object]` supplied to `ContactCell`, expected one of [{"type":"select","defaultValue":"maintain","name":"tendency"},{"type":"select","defaultValue":"distantAcquaintance","name":"group"},{"type":"input","defaultValue":"","name":"firstName"},{"type":"input","defaultValue":"","name":"lastName"},{"type":"input","defaultValue":"","name":"city"},{"type":"input","defaultValue":"","name":"company"},{"type":"input","defaultValue":"","name":"position"}].
    in ContactCell

你如何正确地使用一组可能的对象进行 PropType 检查?

标签: reactjsreact-proptypes

解决方案


prop 类型将oneOf检查引用,但如果您想检查所有属性是否与fields数组中的一个对象匹配,您可以创建一个自定义 prop 类型,使用例如 LodashisEqual将 prop 与fields数组中的对象进行比较。

const fields = [
  { type: "select", defaultValue: MAINTAIN, name: TENDENCY },
  { type: "select", defaultValue: DISTANT_ACQUAINTANCE, name: GROUP },
  { type: "input", defaultValue: "", name: FIRST_NAME },
  { type: "input", defaultValue: "", name: LAST_NAME },
  { type: "input", defaultValue: "", name: CITY },
  { type: "input", defaultValue: "", name: COMPANY },
  { type: "input", defaultValue: "", name: POSITION }
];

ContactCell.propTypes = {
  handleChange: PropTypes.func.isRequired,
  value: PropTypes.string.isRequired,
  field: function(props, propName, componentName) {
    if (
      propName === "field" &&
      !fields.some(field => _.isEqual(props.field, field))
    ) {
      return new Error(
        "Invalid prop `field` supplied to `ContactCell`. Validation failed."
      );
    }
  }
};

推荐阅读