注意: React.PropTypes 自 React v15.5 起已棄用。請使用 prop-types 庫代替。
隨着你的應用的開發,你會使用類型檢查的方法來捕獲很多bug。對於一些應用,你可以使用js擴展就像Flow或者TypeScript去對整個應用進行類型檢查。但是即使你不是用這些擴展語言,React也有一些內置的類型檢查功能。在props上運行類型檢查,你可以指派特殊的propTypes屬性:
import PropTypes from 'prop-types';
class Greeting extends React.Component { render() { return ( <h1>Hello, {this.props.name}</h1> ); } } Greeting.propTypes = { name: PropTypes.string };
PropTypes導出一系列驗證工具可以確保你接收到的數據是有效的。在這個例子里,我們使用PropTypes.string。當一個無效的值被作為prop提供時,一個警告就會出現在js控制台里。因為性能的原因,propTypes只是在開發環境里來使用。
PropTypes
下面是一個不同驗證器的例子:
import PropTypes from '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, // 任何可被渲染的元素(包括數字、字符串、子元素或數組)。 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) ]), // 一個指定元素類型的數組 optionalArrayOf: PropTypes.arrayOf(PropTypes.number), // 一個指定類型的對象 optionalObjectOf: PropTypes.objectOf(PropTypes.number), // 一個指定屬性及其類型的對象 optionalObjectWithShape: PropTypes.shape({ color: PropTypes.string, fontSize: PropTypes.number }), // 你也可以在任何 PropTypes 屬性后面加上 `isRequired` // 后綴,這樣如果這個屬性父組件沒有提供時,會打印警告信息 requiredFunc: PropTypes.func.isRequired, // 任意類型的數據 requiredAny: PropTypes.any.isRequired, // 你也可以指定一個自定義驗證器。它應該在驗證失敗時返回 // 一個 Error 對象而不是 `console.warn` 或拋出異常。 // 不過在 `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: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) { if (!/matchme/.test(propValue[key])) { return new Error( 'Invalid prop `' + propFullName + '` supplied to' + ' `' + componentName + '`. Validation failed.' ); } }) };
限制單個子元素
通過PropTypes.element你可以指定只能有一個子元素被作為children傳遞給一個組件。
import PropTypes from 'prop-types';
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值
你可以定義props的默認值通過分配特殊的defaultProps屬性:
class Greeting extends React.Component { render() { return ( <h1>Hello, {this.props.name}</h1> ); } } // 為屬性指定默認值 Greeting.defaultProps = { name: 'Stranger' }; // 渲染"Hello, Stranger": ReactDOM.render( <Greeting />, document.getElementById('example') );
如果你在使用像 transform-class-properties 的 Babel 轉換器,你也可以在React 組件類中聲明 defaultProps 作為靜態屬性。這個語法還沒有最終通過,在瀏覽器中需要一步編譯工作。更多信息,查看類字段提議。
class Greeting extends React.Component { static defaultProps = { name: 'stranger' } render() { return ( <div>Hello, {this.props.name}</div> ) } }
defaultProps會確保this.props.name將會有一個值如果它沒有被父組件所指定。propTypes類型檢查會在defaultProps解決了之后執行,因此defaultProps也會應用。