🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 属性 props 在使用组件的时候,父组件可以通过`props`向子组件传值,例如 有一个组件 `App.js` 内容如下 ```jsx import React, { Component } from 'react'; const style = { color: '#f00' }; class App extends Component { render() { return ( <div style={style}> Hello {this.props.name} </div> ); } } export default App; ``` `index.js` 中可以通过 props 进行传值: ```jsx import React from 'react'; import ReactDOM from 'react-dom'; import App from './App' ReactDOM.render( <App name='xiaoyu'/>, document.getElementById('root') ); ``` 可以看到,父组件通过属性名向子组件传递值,子组件中通过 `this.props.[xxx]` 取得父组件传入的值。 ## props的不可变性 Props是只读性的,无论是使用函数或是类来声明一个组件,它决不能修改它自己的props。所有的React组件必须像纯函数那样使用它们的props。 ## 扩展属性 如果已经有了个 props 对象,并且想在 JSX 中传递它,可以使用 `...` 作为扩展操作符来传递整个属性对象。下面两个组件是等效的: ```jsx function App() { return <Greeting firstName="Ben" lastName="Hector" />; } ``` ```jsx function App() { const props = {firstName: 'Ben', lastName: 'Hector'}; return <Greeting {...props} />; } ``` ## 类型检查 PropTypes >[warning] 注意: React.PropTypes 自 React v15.5 起已弃用。请使用 [prop-types](https://www.npmjs.com/package/prop-types) 库代替。 随着应用日渐庞大,你可以通过类型检查捕获大量错误。 对于某些应用来说,你还可以使用 Flow 或 TypeScript 这样的 JavsScript 扩展来对整个应用程序进行类型检查。 然而即使不用它们,React 也有一些内置的类型检查功能。 首先安装 prop-types 库 ``` npm install --save prop-types ``` 使用 ```jsx 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可以使下面这些不同的验证器: ```js 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.' ); } }) }; ``` ### 属性默认值 可以通过配置 `defaultProps` 为 props定义默认值。 ```js Greeting.defaultProps = { name: 'Stranger' }; ``` defaultProps 用来确保 this.props.name 在父组件没有特别指定的情况下,有一个初始值。类型检查发生在 defaultProps 赋值之后,所以类型检查也会应用在 defaultProps 上面。 ### 案例 App.js ```js import React, { Component } from 'react'; import PropTypes from 'prop-types'; const style = { color: '#f00' }; class App extends Component { constructor(props) { super(props); this.state = { name: props.name } } render() { return ( <div style={style}> <h2>Hello {this.state.name}</h2> </div> ); } } App.propTypes = { name: PropTypes.string } export default App; ``` index.js ```js import React from 'react'; import ReactDOM from 'react-dom'; import App from './App' const name = 'xiaoyu' ReactDOM.render( <App name={name} />, document.getElementById('root') ); ``` 如上案例,如果传入的 `name = 'xiaoyu'`,为一个字符串,则正常运行,但如果传入一个非字符串的值,比如 `name = 0`,控制台会报一个警告: >[warning] Failed prop type: Invalid prop `name` of type `number` supplied to `App`, expected `string`. 不过程序还是会正常运行。