組件的props是只讀的,組件不能修改自己的props,在React中,組件可以接受任意的props,如函數,對象,基本類型以及react元素
一.props的使用
1.一些組件並不需要知道自己的children,尤其是像Sidebar和Dialog這通用'boxes'的組件。在這些組件中,我們推薦使用特別的children props直接將孩子元素傳遞到組件中。
function FancyBorder(props){
return(
<div>
{props.children}
</div>
)
}
function WelcomeDialog(props){
return <FancyBorder>
<h1>Welcome</h1>
<p>Thank you for visiting our spacecraft!</p>
</FancyBorder>
}
在<FancyBorder>中的任何tag都將作為children props傳遞到FancyBorder組件中
2.你除了可以通過children props直接向組件中傳遞子元素,你也可以按照你自己的習慣,而不是使用children
function FancyBorder(props){
return <div>
{props.top}
{props.bottom}
</div>
}
function WelcomeDialog(props){
return <FancyBorder top={<Top/>} bottom={<Bottom/>} />
}
function Top(props){
return <p> I am top</p>
}
function Bottom(props){
return <p>I am bottom</p>
}
因為React元素(如:<Top>,<Bottom>)只是對象,所以可以將它們作為props傳遞到其他組件中
3.在某些情況下可能需要基於一個普通的組件創建出一個特別的組件。如通過Dialog組件創建出WelcomeDialog組件。在這里我們可以通過配置Dialog組件的props創建出特別的
WelcomeDialog組件。
function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
</FancyBorder>
);
}
function WelcomeDialog() {
return (
<Dialog
title="Welcome"
message="Thank you for visiting our spacecraft!" />
);
}
二.propTypes
從React15.5起,React.PropTypes被移入到單獨的package中。react提供了一個package(prop-types)去檢查props的類型。首先需要將prop-types引用到文件中。
import PropTypes from 'prop-types'
PropTypes暴露了一系列能夠確定接受的props是否合法的驗證器,出於性能的考慮,PropTypes在開發模式下才會起作用
import PropTypes from 'prop-types'
class Greeting extends React.Component{
render(){
return <div>welcome,{this.props.name}</div>
}
}
Greeting.propTypes = {
name:PropTypes.string
}
prop-types提供了大量的驗證器,舉例如下:
import PropTypes from 'prop-types'
myComponent.propTypes = {
// 數組
optionalArray: PropTypes.array,
// 布爾值
optionalBool: PropTypes.bool,
// 函數
optionalFunc: PropTypes.func,
// 數值
optionalNumber: PropTypes.number,
// 對象
optionalObject: PropTypes.object,
// 字符串
optionalString: PropTypes.string,
// symbol
optionalSymbol: PropTypes.symbol,
// 能夠被渲染的數值,字符串,元素或者包含這些類型的數組
optionalNode: PropTypes.node,
// React元素
optionalElement: PropTypes.element,
// optionalMessage是Message類的實例
optionalMessage: PropTypes.instanceOf(Message),
// optionalEnum為['News', 'Photos']中的其中一個
optionalEnum: PropTypes.oneOf(['News', 'Photos']),
//optionalUnion要么為字符串,要么為數值,要么為Message實例
optionalUnion: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message)
]),
// optionalArrayOf是數值類型的數組
optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
// optionalObjectOf的屬性是數值
optionalObjectOf: PropTypes.objectOf(PropTypes.number),
// requiredFunc是函數,且必須提供。isRequired可以鏈接到任何值后面
requiredFunc: PropTypes.func.isRequired,
// requiredAny可以是任何類型,且必須提供
requiredAny: PropTypes.any.isRequired,
// 自定義驗證器。customProp中必須包含matchme
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
}
},
// 自定義數組,對象類型的驗證器
// 驗證器會調用數組或者對象中的每一個值
// customArrayProp中的每一個值都要包含matchme
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.'
);
}
})
}
給props指定默認值
通過組件的defaultProps屬性可以給組件的props指定默認值
import PropTypes from 'prop-types'
class Greeting extends React.Component{
render(){
return <div>welcome,{this.props.name}</div>
}
}
Greeting.defaultProps = {
name:'lili'
}
