如何在实例化时验证React Component道具

时间:2017-07-05 14:26:30

标签: validation reactjs properties

我在另一个组件(Component_A)

中动态创建一个组件(Component_B类型)

如果在支持 id 的情况下缺少Component_B构造函数,则会引发错误。

我想在实例化Component_B时发现错误。

问题是只有在Component_B附加到Component_A后才会调用构造函数(见下文)。

class Component_A extends React.Component {

    constructor(props) {
        this.addComponentB = this.addComponentB.bind(this);
    }


    addComponentB(data) {

        return (
            <Component_B name=data.name />
        )
    }

    renderComponentB() {
        ...
        compB = null
        try {   
            compB = this.addComponentB({'name'='hello'});

        catch(e) {
          // I would like to catch an error here, if the 'id' prop is not set for component_B
        }

        return (
            compB
        )

    }

    render() {
        return (
            <div>{this.renderComponentB}</div>
        )
    }
}    



class Component_B extends React.Component {

    constructor(props) {
        super(props)

        // Solution 1
        if(!props.id){
            console.debug('if not id')
            throw 'Cant create a Component_B with no ID!';
        }
    }

    render() {
        return ....
    }
}

我也尝试使用propTypes,但它也不起作用:

// Solution 2
Component_B.propTypes = {
  id: PropTypes.string.isRequired
};

1 个答案:

答案 0 :(得分:0)

我猜你可以手动检查所有这些道具。例如,我就是这样做的:

VALID_BUTTON_ATTRS: [
    'autofocus',
    'autocomplete',
    'disabled',
    'form',
    'formaction',
    'formenctype',
    'formmethod',
    'formnovalidate',
    'formtarget',
    'name',
    'type',
    'value'
],
GLOBAL_ATTRS: [
    'accesskey',
    // 'class',
    // Note: React specific, all needs to be lower case
    'classname',
    'contenteditable',
    'contextmenu',
    // 'data-*', needs to test specifically
    // Note: React specific
    'dangerouslysetinnerhtml',
    'dir',
    'draggable',
    'dropzone',
    'hidden',
    'id',
    'itemid ',
    'itemprop ',
    'itemref',
    'itemscope',
    'itemtype',
    'lang',
    'slot',
    'spellcheck',
    'style',
    'tabindex',
    'title',
    'translate'
],
EVENT_ATTRS: [
    'onabort',
    'onautocomplete',
    'onautocompleteerror',
    'onblur',
    'oncancel',
    'oncanplay',
    'oncanplaythrough',
    'onchange',
    'onclick',
    'onclose',
    'oncontextmenu',
    'oncuechange',
    'ondblclick',
    'ondrag',
    'ondragend',
    'ondragenter',
    'ondragexit',
    'ondragleave',
    'ondragover',
    'ondragstart',
    'ondrop',
    'ondurationchange',
    'onemptied',
    'onended',
    'onerror',
    'onfocus',
    'oninput',
    'oninvalid',
    'onkeydown',
    'onkeypress',
    'onkeyup',
    'onload',
    'onloadeddata',
    'onloadedmetadata',
    'onloadstart',
    'onmousedown',
    'onmouseenter',
    'onmouseleave',
    'onmousemove',
    'onmouseout',
    'onmouseover',
    'onmouseup',
    'onmousewheel',
    'onpause',
    'onplay',
    'onplaying',
    'onprogress',
    'onratechange',
    'onreset',
    'onresize',
    'onscroll',
    'onseeked',
    'onseeking',
    'onselect',
    'onshow',
    'onsort',
    'onstalled',
    'onsubmit',
    'onsuspend',
    'ontimeupdate',
    'ontoggle',
    'onvolumechange',
    'onwaiting'
]

然后,使用以下方法检查:

_.forEach(props, (value, key) => {
    // test data-*
    if (/^data-\w*$/i.test(key) ||
        // for valid key
        htmlConstants.VALID_BUTTON_ATTRS.indexOf(key.toLowerCase()) > -1 ||
        htmlConstants.GLOBAL_ATTRS.indexOf(key.toLowerCase()) > -1 ||
        htmlConstants.EVENT_ATTRS.indexOf(key.toLowerCase()) > -1) {
        validAttrs[key] = value;
    }
});