1.基本說明
PropTypes定義為組件類自身的屬性,用以定義prop的類型。在開發模式下,當提供一個不合法的值作為prop時,控制台會出現警告;
在產品模式下,為了性能考慮應忽略propTypes
Prop types 是一個在運行時使用的新特性. 我們能夠通過下面的方式在我們的團隊里邊使用.
2.版本更新
在15.5版本之后, 代替使用 PropTypes 直接從 React 對象這種導入方式, 安裝一個新的包 prop-types 並且使用如下的方式進行導入:
// After (15.5)
import React from 'react';
import PropTypes from 'prop-types';
class Component extends React.Component {
render() {
return <div>{this.props.text}</div>;
}
}
Component.propTypes = {
text: PropTypes.string.isRequired,
};
如下代碼,為之前的書寫方式
// Before (15.4 and below)
import React from 'react';
class Component extends React.Component {
render() {
return <div>{this.props.text}</div>;
}
}
Component.propTypes = {
text: React.PropTypes.string.isRequired,
}
由於版本不一致,一般會導致如下錯誤:
Unhandled JS Exception: Cannot read property 'string' of undefined
只要按照版本對應起來使用就可以了
3.具體使用
靜態屬性,只能通過類名.屬性名指定
class Greeting extends React.Component {
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}
Greeting.propTypes = { // 靜態屬性,只能通過類名.屬性名指定
name: PropTypes.string
};
React.PropTypes輸出一系列的驗證器,用以確保你收到的數據是合法的。
下面是一個例子記錄了不同的驗證器;
MyComponent.propTypes = {
// 可以聲明prop是特定的JS基本類型
// 默認情況下這些prop都是可選的
optionalArray:PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,
// 任何可以被渲染的事物:numbers, strings, elements or an array
// (or fragment) containing these types.
optionalNode: PropTypes.node,
// A React element.
optionalElement: PropTypes.element,
// 聲明一個prop是某個類的實例,用到了JS的instanceof運算符
optionalMessage: PropTypes.instanceOf(Message),
// 用enum來限制prop只接受特定的值
optionalEnum: PropTypes.oneOf(['News', 'Photos']),
// 指定的多個對象類型中的一個
optionalUnion: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message)
]),
// 指定類型組成的數組
optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
// 指定類型的屬性構成的對象
optionalObjectOf: PropTypes.objectOf(PropTypes.number),
// 一個指定形式的對象
optionalObjectWithShape: PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number
}),
// 你可以用以上任何驗證器鏈接‘isRequired’,來確保prop不為空
requiredFunc: PropTypes.func.isRequired,
// 不可空的任意類型
requiredAny: PropTypes.any.isRequired,
// 自定義驗證器,如果驗證失敗,必須返回一個Error對象
// 不要直接使用console.warn或者throw,這些在oneOfType中都沒用
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
}
},
// 你也可以為arrayOf和objectOf提供一個驗證器
// 如果驗證失敗,它也應該返回一個Error對象
// 在array或者object中,驗證器對於每個key都會被調用The first two
// 驗證器的前兩個arguments是array或者object自身以及當前的key值
customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
if (!/matchme/.test(propValue[key])) {
return new Error(
'Invalid prop `' + propFullName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
}
})
};
Requiring Single Child
你可以使用React.PropTypes.element指定僅可以將單一子元素作為子節點傳遞給組件。
class MyComponent extends React.Component {
render() {
// This must be exactly one element or it will warn.
const children = this.props.children;
return (
<div>
{children}
</div>
);
}
}
MyComponent.propTypes = {
children: PropTypes.element.isRequired
};
默認Prop值
通過賦值特殊的defaultProps屬性,你可以為props定義默認值:
class Greeting extends React.Component {
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}
// Specifies the default values for props:
Greeting.defaultProps = {
name: 'Stranger'
};
// Renders "Hello, Stranger":
ReactDOM.render(
<Greeting />,
document.getElementById('example')
);
如果父組件沒有為this.props.name傳值,defaultProps會給其一個默認值。propTypes的類型檢測是在defaultProps解析之后發生的,因此也會對默認屬性defaultProps進行類型檢測。
4.無狀態組件的檢查和默認設置
如下面所示,對無狀態組件進行設置
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { View, Text, TextInput } from 'react-native';
const TextSegment = (props) => {
const {
behindStyle,
delimiter,
delimiterStyle,
frontStyle,
value,
style,
} = props;
let frontValue = '';
let behindValue = '';
const splits = value && delimiter && value.split(delimiter);
if (splits && splits.length) {
frontValue = splits[0];
behindValue = splits[1];
}
if (!delimiter) {
return (
<View style={[{ flexDirection: 'row' }, style]}>
<Text style={frontStyle}>{value}</Text>
</View>
);
}
return (
<View style={[{ flexDirection: 'row' }, style]}>
<Text style={frontStyle}>{frontValue}</Text>
<Text style={delimiterStyle}>{delimiter}</Text>
<Text style={behindStyle}>{behindValue}</Text>
</View>
);
};
TextSegment.propTypes = {
frontStyle: TextInput.propTypes.style,
delimiterStyle: TextInput.propTypes.style,
behindStyle: TextInput.propTypes.style,
style: View.propTypes.style,
delimiter: PropTypes.string,
value: PropTypes.string,
};
TextSegment.defaultProps = {
style: {
alignItems: 'flex-end',
},
value: '',
};
export default TextSegment;
在上面代碼中,通過方法名進行引用propTypes和defaultProps,其他用法和組件中使用一致。
