1. 程式人生 > >React學習筆記—元件複用

React學習筆記—元件複用

Prop 驗證

隨著應用不斷變大,保證元件被正確使用變得非常有用。為此我們引入propTypes。React.PropTypes 提供很多驗證器 (validator) 來驗證傳入資料的有效性。當向 props 傳入無效資料時,JavaScript 控制檯會丟擲警告。注意為了效能考慮,只在開發環境驗證 propTypes。下面用例子來說明不同驗證器的區別:

React.createClass({
  propTypes: {
    // 可以宣告 prop 為指定的 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,

    // 所有可以被渲染的物件:數字,
    // 字串,DOM 元素或包含這些型別的陣列。
    optionalNode: React.PropTypes.node,

    // React 元素
    optionalElement: React.PropTypes.element,

    // 用 JS 的 instanceof 操作符宣告 prop 為類的例項。
    optionalMessage: React.PropTypes.instanceOf(Message),

    // 用 enum 來限制 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` 來使 prop 不可空。
    requiredFunc: React.PropTypes.func.isRequired,

    // 不可空的任意型別
    requiredAny: React.PropTypes.any.isRequired,

    // 自定義驗證器。如果驗證失敗需要返回一個 Error 物件。不要直接
    // 使用 `console.warn` 或拋異常,因為這樣 `oneOfType` 會失效。
    customProp: function(props, propName, componentName) {
      if (!/matchme/.test(props[propName])) {
        return new Error('Validation failed!');
      }
    }
  },
  /* ... */
});

預設 Prop 值

React 支援以宣告式的方式來定義 props 的預設值。

var ComponentWithDefaultProps = React.createClass({
  getDefaultProps: function() {
    return {
      value: 'default value'
    };
  }
  /* ... */
});

當父級沒有傳入 props 時,getDefaultProps() 可以保證 this.props.value 有預設值,注意 getDefaultProps 的結果會被 快取。得益於此,你可以直接使用 props,而不必寫手動編寫一些重複或無意義的程式碼。

傳遞 Props:小技巧

有一些常用的 React 元件只是對 HTML 做簡單擴充套件。通常,你想少寫點程式碼來把傳入元件的 props 複製到對應的 HTML 元素上。這時 JSX 的 spread 語法會幫到你:

var CheckLink = React.createClass({
  render: function() {
    // 這樣會把 CheckList 所有的 props 複製到 <a>
    return <a {...this.props}>{'√ '}{this.props.children}</a>;
  }
});

React.render(
  <CheckLink href="/checked.html">
    Click here!
  </CheckLink>,
  document.getElementById('example')
);
單個子級
React.PropTypes.element 可以限定只能有一個子級傳入。

var MyComponent = React.createClass({
  propTypes: {
    children: React.PropTypes.element.isRequired
  },

  render: function() {
    return (
      <div>
        {this.props.children} // 有且僅有一個元素,否則會拋異常。
      </div>
    );
  }

});