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),
};