React從入門到精通系列之(13)使用PropTypes進行型別檢測

張亞濤發表於2016-12-15

十三、使用PropTypes進行型別檢測

隨著你的應用的變得越來越大,你可以通過typechecking來找到更多的bug。 對於某些應用,您可以使用JavaScript擴充套件(如FlowTypeScript)對整個應用程式進行型別檢查。

即使你不使用這些,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`)
)

如果父元件沒有設定並傳入namedefaultProps將確保this.props.name將有一個預設值。 propTypes型別檢查發生在defaultProps解析之後,因此型別檢查也將應用於defaultProps

相關文章