React(三)——React組件之props驗證

目錄

1.props 驗證

1.1prop-types

1.2安裝

1.3使用


1.props 驗證

隨着應用的不斷增長,也是爲了使程序設計更加嚴謹,我們通常需要對數據的類型(值)進行一些必要的驗證,React.js 提供了一個驗證庫:prop-types。

在程序運行時就能檢測出錯誤。

這個驗證是針對程序員程序開發存在,不能使用到用戶交互提醒用戶操作錯誤等。

1.1prop-types

prop-types 是一個獨立的庫,需要安裝

https://www.npmjs.com/package/prop-types

1.2安裝

進入到項目路徑,輸入命令後,會在node_modules下安裝prop-types包:

npm i -S prop-types

1.3使用

import PropTypes from 'prop-types';

它的使用並不複雜,與 defaultProps 類似,我們在組件類下添加一個靜態屬性 propTypes (屬性名不能更改),它的值也是一個對象,用來設置組件中props的驗證規則,key 是要驗證的屬性名稱,value 是驗證規則。

  • 動態屬性:加在this即new出來的實例對象上,即實例對象屬性;
  • 靜態屬性:構造函數或類上的屬性

prop-types提供很多已有的驗證規則。如,驗證是否是數組,是否爲節點,是否爲某個類的實例(PropTypes.instanceof(Message))

示例:

static propTypes = {

   title:PropTypes.string.isRequired //必須是字符串且必傳

}

如果title沒有傳,則再console下回報錯。

後期建議用typescript進行替代更好

MyComponent.propTypes = {
  // You can declare that a prop is a specific JS primitive. By default, these
  // are all optional.
  optionalArray: PropTypes.array,
  optionalBool: PropTypes.bool,
  optionalFunc: PropTypes.func,
  optionalNumber: PropTypes.number,
  optionalObject: PropTypes.object,
  optionalString: PropTypes.string,
  optionalSymbol: PropTypes.symbol,
 
  // Anything that can be rendered: numbers, strings, elements or an array
  // (or fragment) containing these types.
//驗證是否爲節點
  optionalNode: PropTypes.node,
 
//驗證是否爲元素
  // A React element (ie. <MyComponent />).
  optionalElement: PropTypes.element,
 
//驗證是否爲元素類型
  // A React element type (ie. MyComponent).
  optionalElementType: PropTypes.elementType,
 
//驗證是否爲另一個類的實例
  // You can also declare that a prop is an instance of a class. This uses
  // JS's instanceof operator.
  optionalMessage: PropTypes.instanceOf(Message),
 
//驗證傳入值是否在給定範圍
  // You can ensure that your prop is limited to specific values by treating
  // it as an enum.
  optionalEnum: PropTypes.oneOf(['News', 'Photos']),
 
//驗證傳入類型是否在給定範圍
  // An object that could be one of many types
  optionalUnion: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(Message)
  ]),
 
  // An array of a certain type
  optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
 
  // An object with property values of a certain type
  optionalObjectOf: PropTypes.objectOf(PropTypes.number),
 
  // You can chain any of the above with `isRequired` to make sure a warning
  // is shown if the prop isn't provided.
 
  // An object taking on a particular shape
  optionalObjectWithShape: PropTypes.shape({
    optionalProperty: PropTypes.string,
    requiredProperty: PropTypes.number.isRequired
  }),
 
  // An object with warnings on extra properties
  optionalObjectWithStrictShape: PropTypes.exact({
    optionalProperty: PropTypes.string,
    requiredProperty: PropTypes.number.isRequired
  }),
 
  requiredFunc: PropTypes.func.isRequired,
 
  // A value of any data type
  requiredAny: PropTypes.any.isRequired,
 
  // You can also specify a custom validator. It should return an Error
  // object if the validation fails. Don't `console.warn` or throw, as this
  // won't work inside `oneOfType`.
//回調函數:自定義驗證規則
  customProp: function(props, propName, componentName) {
    if (!/matchme/.test(props[propName])) {
      return new Error(
        'Invalid prop `' + propName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  },
 
  // You can also supply a custom validator to `arrayOf` and `objectOf`.
  // It should return an Error object if the validation fails. The validator
  // will be called for each key in the array or object. The first two
  // arguments of the validator are the array or object itself, and the
  // current item's key.
  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.'
      );
    }
  })
};

示例:

dialog.css:

.dialog {
    position: fixed;
    left: 50%;
    top: 30%;
    transform: translateX(-50%) translateY(-50%) ;
    border-radius: 2px;
    box-shadow: 0 1px 3px rgba(0,0,0,.3);
    box-sizing: border-box;
    background: #fff;
    width: 30%;
}
.dialog_header {
    padding: 20px 20px 0;
    text-align: left;
}
.dialog_title {
    font-size: 16px;
    font-weight: 700;
    color: #1f2d3d;
}
.dialog_content {
    padding: 30px 20px;
    color: #48576a;
    font-size: 14px;
    text-align: left;
}
.dialog_close_btn {
    position: absolute;
    right: 10px;
    top: 5px;
}
.dialog_close_btn:before {
    content: 'x';
    color: #999;
    font-size: 20px;
    cursor: pointer;
}

App.js:

import React from 'react';
import './App.css';

import Dialog from './components/Dialog';

function App() {

  return (
    <div className="App">
      <Dialog>
        {/* 整個form表單都是作爲內容傳遞給子組件Dialog,子組件通過this.props.children可以得到整個form表單結構 */}
        <form id="dialog_form" method="post">
          用戶名:<input type="text" name="name" />
        </form>
      </Dialog>
    </div>
  );
}

export default App;

Dialog.js:

import React from 'react';
import '../css/dialog.css';
import PropTypes from 'prop-types';

class Dialog extends React.Component {
    static propTypes = {
        title : PropTypes.string.isRequired
     }
    render() {
        return (
            <div className="dialog">
                <i className="dialog_close_btn"></i>
                <div className="dialog_header">
                    <span className="dialog_title">{this.props.title}</span>
                </div>
                <div className="dialog_content">
                    {this.props.children}
                </div>
            </div>
        );
    }
}

export default Dialog;

效果:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章