為什么需要類型檢查?
JavaScript 是一門弱類型的語言,允許變量類型做隱式轉換。也正是因為這個特性,JavaScript 中有很多錯誤都是類型錯誤導致的。為了減少這種錯誤,我們可以在 React 中引入類型檢查模塊。
React 中的類型檢查:prop-types 包
例子
-
導入包
import PropTypes from 'prop-types'; -
編寫組件
class Greeting extends React.Component { render() { return <h1>Hello, {this.props.name}</h1> } } -
新增類型檢查
Greeting.propTypes = { name: PropTypes.string } -
檢驗類型檢查
我們把 Greeting 組件的屬性 name 設置成 String 類型,也就是說父組件通過該屬性傳遞數(shù)據(jù)的時候,需要傳遞 String 類型的數(shù)據(jù),否則會顯示類型錯誤的警告。
我們可以嘗試傳遞一個數(shù)字類型的屬性:
<div> <Greeting name={123} /> </div>可以看到頁面中會出現(xiàn)類型錯誤的告警:
PropTypes 包含一整套驗證器,可用于確保你接收的數(shù)據(jù)是有效的。在上面的示例中,我們使用了 PropTypes.string。
出于性能原因,propTypes 只在開發(fā)模式下進行檢查。
prop-types 的多種驗證器
MyComponent.propTypes = {
// 屬性可以聲明為 JS 原生類型
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,
/* 任何東西都可以被渲染:numbers, strings, elements,或者是包含這些類型的數(shù)組(或者是片段)。*/
optionalNode: PropTypes.node,
// 一個 React 元素。
optionalElement: PropTypes.element,
// 屬性也可以聲明為類的一個實例。
// 使用 JS 的 instanceof 運算符。
optionalMessage: PropTypes.instanceOf(Message),
// 屬性聲明為特定的值,類似于枚舉
optionalEnum: PropTypes.oneOf(['News', 'Photos']),
// 一個對象可以是多種類型其中之一
optionalUnion: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message)
]),
// 一個某種類型的數(shù)組
optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
// 屬性值為某種類型的對象
optionalObjectOf: PropTypes.objectOf(PropTypes.number),
// 一個特定形式的對象
optionalObjectWithShape: PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number
}),
// 使用 'isRequired' 鏈接上述的類型設定,可以確保在沒有提供 Props 的情況下顯示警告。
requiredFunc: PropTypes.func.isRequired,
// 任何數(shù)據(jù)類型的值
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對象。
// 可以在數(shù)組或者對象的每一個元素上調(diào)用驗證器。驗證器的前兩個參數(shù)分別是數(shù)組或者對象本身和當前元素的鍵值。
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.'
);
}
})
};
屬性默認值
你可以通過配置 defaultProps 為 Props 定義默認值:
// 為屬性指定默認值:
Greeting.defaultProps = {
name: 'Stranger'
};
defaultProps 用來確保 this.props.name 在父組件沒有特別指定的情況下,有一個初始值。類型檢查發(fā)生在 defaultProps 賦值之后,所以類型檢查也會應用在 defaultProps 上面,我們也需要保證所設置的默認值符合類型檢查設定的類型。
使用 PropTypes.element 限制單個子代
使用 PropTypes.element,可以指定只傳遞一個子代
例子
import PropTypes from 'prop-types';
class MyComponent extends React.Component {
render() {
const children = this.props.children;
return (
<div>
{children}
</div>
);
}
}
MyComponent.propTypes = {
children: PropTypes.element.isRequired
};
this.props.children 是父組件在 MyComponent 中添加的子節(jié)點,當 children 包含多個兄弟節(jié)點,而不是只有一個節(jié)點時,會打印錯誤告警。
錯誤:
<div>
<MyComponent>
<div>hello</div>
<div>props</div>
</MyComponent>
</div>
正確:
<div>
<MyComponent>
<div>hello props</div>
</MyComponent>
</div>
參考文章:使用 PropTypes 進行類型檢查