十三、使用PropTypes進行型別檢測
隨著你的應用的變得越來越大,你可以通過typechecking
來找到更多的bug。 對於某些應用,您可以使用JavaScript擴充套件(如Flow
或TypeScript
)對整個應用程式進行型別檢查。
即使你不使用這些,React也有一些內建的typechecking
能力。 要在元件的props
上執行typechecking
,可以分配特殊的propTypes
屬性:
class Greeting extends React.Component {
render() {
return (
<h1>Hello {this.props.name}</h1>
)
};
}
Greeting.propTypes = {
name: React.PropTypes.string.isRequired
};
React.PropTypes
返回的是一系列驗證函式,用於確保接收的資料類似是否是有效的。
在這個例子中,我們使用React.PropTypes.string.isRequire
檢測name
是否為字串,並且是必填的。
當為prop提供無效值時,JavaScript控制檯中將顯示警告。 出於效能原因,僅在開發模式下檢查propTypes
。
React.PropTypes
下面是一個示例,其中提供了不同的驗證函式:
MyComponent.propTypes = {
// 你可以定義一個js原始型別的prop,預設請情況下,這是都是可選的
optionalArray: React.PropTypes.array,
optionalBool: React.PropTypes.bool,
optionalFunc: React.PropTypes.func,
optionalNumber: React.PropTypes.number,
optionalObject: React.PropTypes.object,
optionalString: React.PropTypes.string,
optionalSymbol: React.PropTypes.symbol,
// 任何可以渲染的東西:數字,字串,元素或陣列(或片段)。
optionalNode: React.PropTypes.node,
// React元素
optionalElement: React.PropTypes.element,
// 你也可以宣告prop是某個類的例項。 內部使用的是JS的instanceof運算子。
optionalMessage: React.PropTypes.instanceOf(Message),
// 你可以通過將它作為列舉來確保你的prop被限制到特定的值。
optionalEnum: React.PropTypes.oneOf([`News`, `Photos`]),
// 可以是許多型別之一的物件
optionalUnion: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number,
React.PropTypes.instanceOf(Message)
]),
// 某種型別的陣列
optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
// 具有某種型別的屬性值的物件
optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
// 採取特定樣式的物件
optionalObjectWithShape: React.PropTypes.shape({
color: React.PropTypes.string,
fontSize: React.PropTypes.number
}),
// 你可以用`isRequired`來連線到上面的任何一個型別,以確保如果沒有提供props的話會顯示一個警告。
requiredFunc: React.PropTypes.func.isRequired,
// 任何資料型別
requiredAny: React.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物件。
// 檢查器將為陣列或物件中的每個鍵呼叫驗證函式。
// 檢查器有兩個引數,第一個引數是陣列或物件本身,第二個是當前項的鍵。
customArrayProp: React.PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
if (!/matchme/.test(propValue[key])) {
return new Error(
`Invalid prop `` + propFullName + `` supplied to` +
` `` + componentName + ``. Validation failed.`
);
}
})
};
要求只能是單個子元素
使用React.PropTypes.element
,您可以指定只有一個子元素可以作為內容傳遞的元件。
class MyComponent extends React.Component {
render() {
// 只能包含一個子元素,否則會給出警告
const children = this.props.children;
return (
<div>{children}</div>
);
}
}
MyComponent.propTypes = {
children: React.PropTypes.element.isRequired
}
設定Prop預設值
您可以通過使用defaultProps
屬性來定義props的預設值:
class Greeting extends React.Component {
render() {
return <h1>hello {this.props.name}</h1>;
};
}
// 如果name沒有傳值,則會將name設定為預設的zhangyatao
Greeting.defaultProps = {
name: `zhangyatao`
}
// 會渲染處<h1>hi zhangyatao</h1>
ReactDOM.render(
<Greeting />,
document.getElementById(`root`)
)
如果父元件沒有設定並傳入name
,defaultProps
將確保this.props.name
將有一個預設值。 propTypes
型別檢查發生在defaultProps
解析之後,因此型別檢查也將應用於defaultProps
。