Javascript 特定组件的类型?

Javascript 特定组件的类型?,javascript,reactjs,Javascript,Reactjs,我有一个简单的反应组件: import {PropTypes} from 'react'; import Column from './Column'; export default function ColumnContainer({children}) { return ( <div className="cr-column-container">{children}</div> ); } let ColumnType = Prop

我有一个简单的反应组件:

import {PropTypes} from 'react';
import Column from './Column';

export default function ColumnContainer({children}) {
    return (
        <div className="cr-column-container">{children}</div>
    );
}

let ColumnType = PropTypes.instanceOf(Column);

ColumnContainer.propTypes = {
    children: PropTypes.oneOfType([
        ColumnType,
        PropTypes.arrayOf(ColumnType),
    ]).isRequired,
};

为什么呢?我只使用了ColumnContainer中的列。PropTypes.InstanceOffColumn是否不像我预期的那样工作?如何指定ColumnContainer只接受Column类型的子项?

进行了一些挖掘,根据以下内容提出了此帮助函数:

用法:

ColumnContainer.propTypes = {
    children: childrenOf(Column).isRequired,
};
它并不理想,因为它不支持像“div”这样的本机DOM元素,并且错误消息毫无价值,但现在就可以了。

我通过对react hot loader 4.x的支持对childrenOf进行了大修:

import { areComponentsEqual } from 'react-hot-loader';

export function childrenOf(...types) {
    return requirable((props, propName, componentName, location, propFullName) => {
        const component = props[propName];
        if(!location) {
            location = 'prop';
        }
        if(!propFullName) {
            propFullName = propName;
        }
        const check = c => types.some(type => areComponentsEqual(type,c.type));
        const valid = Array.isArray(component) ? component.every(check) : check(component);
        if(!valid) {
            return new Error(
                `Invalid ${location} \`${propFullName}\` supplied to \`${componentName}\`. Every element must be a <${types.map(t => getDisplayName(t)).join('|')}>.`
            );
        }
        return null;
    });
}

function requirable(predicate) {
    const propType = (props, propName, ...rest) => {
        // don't do any validation if empty
        if(props[propName] === undefined) {
            return null;
        }

        return predicate(props, propName, ...rest);
    };

    propType.isRequired = (props, propName, componentName, ...rest) => {
        // warn if empty
        if(props[propName] === undefined) {
            return new Error(`Required prop \`${propName}\` was not specified in \`${componentName}\`.`);
        }

        return predicate(props, propName, componentName, ...rest);
    };

    return propType;
}
用法示例:

export function TBody({children, ...attrs}) {
    return <tbody {...attrs}>{children}</tbody>;
}

TBody.propTypes = {
    children: WxTypes.childrenOf(TRow),
};

看看这个:@jamesemanon刚刚发现了这个。不过,提出的解决方案都不理想。
ColumnContainer.propTypes = {
    children: childrenOf(Column).isRequired,
};
import { areComponentsEqual } from 'react-hot-loader';

export function childrenOf(...types) {
    return requirable((props, propName, componentName, location, propFullName) => {
        const component = props[propName];
        if(!location) {
            location = 'prop';
        }
        if(!propFullName) {
            propFullName = propName;
        }
        const check = c => types.some(type => areComponentsEqual(type,c.type));
        const valid = Array.isArray(component) ? component.every(check) : check(component);
        if(!valid) {
            return new Error(
                `Invalid ${location} \`${propFullName}\` supplied to \`${componentName}\`. Every element must be a <${types.map(t => getDisplayName(t)).join('|')}>.`
            );
        }
        return null;
    });
}

function requirable(predicate) {
    const propType = (props, propName, ...rest) => {
        // don't do any validation if empty
        if(props[propName] === undefined) {
            return null;
        }

        return predicate(props, propName, ...rest);
    };

    propType.isRequired = (props, propName, componentName, ...rest) => {
        // warn if empty
        if(props[propName] === undefined) {
            return new Error(`Required prop \`${propName}\` was not specified in \`${componentName}\`.`);
        }

        return predicate(props, propName, componentName, ...rest);
    };

    return propType;
}
export function TBody({children, ...attrs}) {
    return <tbody {...attrs}>{children}</tbody>;
}

TBody.propTypes = {
    children: WxTypes.childrenOf(TRow),
};