原文链接;React完整笔记
React三大属性之Props
React 组件使用 props 来互相通信。每个父组件都可以提供 props 给它的子组件,从而将一些信息传递给它。Props 可能会让你想起 HTML 属性,但你可以通过它们传递任何 JavaScript 值,包括对象、数组和函数。
Props 是你传递给 JSX 标签的信息。例如,className
、src
、alt
、width
和 height
便是一些可以传递给 <img>
的 props:
我们在渲染组件的时候,可以给组件传递一些属性,例如我创建了一个PersonComponent
组件,将组件渲染到界面上:
class PersonComponent extends React.Component {
render() {
}
}
ReactDOM.render(<PersonComponent name='橘柚' age={20}/>, document.getElementById("demo"))
此时我们通过React调试工具发现,在组件标签上面传递过来的属性全部转化到组件的三大属性props
上面了,

所以我们可以通过访问this.props
,在组件中拿到name
和age
注意:props是只读的,所以不能修改
class PersonComponent extends React.Component {
render() {
const {name, age} = this.props
return <p>我叫{name},今年{age}岁</p>
}
}
ReactDOM.render(<PersonComponent name='橘柚' age='20'/>, document.getElementById("demo"))
显示结果:

1)props语法糖
如果我们在组件标签上面传递的属性过多怎么办?我们可以通过React语法糖{...实现}
const p = {
name: '橘柚',
age: 20
}
ReactDOM.render(<PersonComponent {...p}/>, document.getElementById("demo"))
2)限制props
a、props传递的数据类型
看下面的代码,我想年龄+1输出
class PersonComponent extends React.Component {
render() {
const {name, age} = this.props
return <p>我叫{name},今年{age + 1}岁</p>
}
}
ReactDOM.render(<PersonComponent name="橘柚" age="20"/>, document.getElementById("demo"))
结果却是字符串拼接输出,是因为age="20"
通过双引号传值,返回的是字符串类型,所以才会拼接,想要传递number
类型需要使用React的{}

修改代码如下:age={20}
ReactDOM.render(<PersonComponent name="橘柚" age={20}/>, document.getElementById("demo"))
b、限制传递的数据类型
在React 16.xxx以后,想要限制数据类型需要引入
prop-types.js
这个库
<!--引入React的核心库-->
<script type="text/javascript" src="./react-js/react.development.js"></script>
<!--引入React-DMO的核库-->
<script type="text/javascript" src="./react-js/react-dom.development.js"></script>
<!--引入babel-->
<script type="text/javascript" src="./react-js/babel.min.js"></script>
<!--限制props类型-->
<script type="text/javascript" src="./react-js/prop-types.js"></script>
在上面的四条引用中,引用react.development.js
全局就添加了一个对象React
,引入react-dom.development.js
全局就多了一个对象ReactDom
,引入prop-types.js
,全局就多了一个对象PropTypes
,用于使用props做类型限制。
我们想要给组件的props做类型限制,需要在组件里面添加propTypes
的属性:
class PersonComponent extends React.Component {
...省略render
}
// 指定类型限制
PersonComponent.propTypes = {
name: PropTypes.string,
age: PropTypes.number
}
ReactDOM.render(<PersonComponent name="橘柚" age="20"/>, document.getElementById("demo"))
上面代码限制age
为number
类型,但是传递的却是string
,所以会报错:

c、必要性限制
同类型限制一样,只需要添加isRequired
即可,这样在传递属性的时候,name
不能缺失,否则报错
PersonComponent.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number
}
d、props默认值
如果props属性没传递,可以给属性指定默认值,需要在组件里面再指定一个dedfaultProps
属性:
class PersonComponent extends React.Component {
...省略render
}
PersonComponent.propTypes = {
name: PropTypes.string, // 此处没有指定isRequired
age: PropTypes.number
}
// 添加默认值
PersonComponent.defaultProps = {
name: '张三'
}
// 此处并没有传递name的值
ReactDOM.render(<PersonComponent age="20"/>, document.getElementById("demo"))
e、限制传递函数类型
函数的类型为func
而不是function
,那是因为function
为JS的关键字
PersonComponent.propTypes = {
speak: PropTypes.func
}
下面是完整的实现案例:
class PersonComponent extends React.Component {
render() {
const {name, age, speak} = this.props
speak()
return <p>我叫{name},今年{age + 1}岁</p>
}
}
PersonComponent.propTypes = {
name: PropTypes.string,
age: PropTypes.number,
speak: PropTypes.func
}
PersonComponent.defaultProps = {
name: '张三'
}
const p = {
name: '橘柚',
age: 22
}
function speak() {
console.log(`我叫${p.name},今年${p.age}岁`)
}
ReactDOM.render(<PersonComponent {...p} speak={speak}/>, document.getElementById("demo"))
3)props简写
我们在做PersonComponent.propTypes = {}
这个操作的本质就是给类的本身添加属性,这里要区分给类的实例添加属性,propTypes
是添加在类身上的,而下面的操作属性会添加在属性上:
class PersonComponent extends React.Component {
propTypes = {
name: PropTypes.string,
age: PropTypes.number,
speak: PropTypes.func
}
...
}
我们想要给类添加属性,需要用到static
关键字进行修饰:
class PersonComponent extends React.Component {
static propTypes = {
name: PropTypes.string,
age: PropTypes.number,
speak: PropTypes.func
}
static defaultProps = {
name: '张三'
}
render() {
const {name, age, speak} = this.props
speak()
return <p>我叫{name},今年{age + 1}岁</p>
}
}
4)函数组件的props
上面提到的三大组件都是基于类的实例的,虽然函数不能创建实例,但是函数可以接收参数,所以在函数组件里面可以操作props
,但是其他两个组件就不能实现了。
我们可以在函数的参数里面接收一个props,然后就可以使用了
function Person(props) {
return (
<h1>我叫{props.name},今年{props.age}岁</h1>
)
}
ReactDOM.render(<Person name={'橘柚'} age={22}/>, document.getElementById("demo"))
函数式组件的类型限制
函数式组件的类型限制只能写在组件的外测:
function Person(props) {
return (
<h1>我叫{props.name},今年{props.age}岁</h1>
)
}
Person.propTypes = {
name: PropTypes.string
}
Person.defaultProps = {
name: '张三'
}