React学习笔记(5) - 类组件中的属性(props)

  • React中的属性(props)与Vue中的父子组件间通信(props)非常的相似,使用方法也非常的相似,都是通过在父组件中调用子组件,随后在父组件中,通过key="value"或者key={value}的方式将属性(props)传给子组件,随后子组件再通过this.props来接受父组件传过来的属性。但是,props是正常是外部传入的,组件内部也可以通过一些方式来初始化的设置,属性不能被组件自己更改,也就是说,你可以认为在子组件中,父组件传过来的属性(props)是只读的(readonly),子组件不能更改这个属性,但你可以通过父组件主动重新渲染的方式来传入新的props,属性是描述性质、特点的,组件自己不能随意更改。

代码展示:

  • 父组件
import React, { Component } from 'react'
import Naviber from './Naviber'
export default class App extends Component {
render() {
// 使用props(属性)传值(父组件通过key=value的形式传值给子组件)类似于Vue的props
var obj = {//同样可以以es6对象展开的形式传属性给子组件
title="cart",
isShowBtn=true
}
return (
<div>
<div>
<h2>首页</h2>
{/* 将title属性和isShowBtn传给子组件 */}
<Naviber title="home" isShowBtn={false}/>
</div>

<div>
<h2>列表</h2>
<Naviber title="list" isShowBtn={true}/>
</div>

<div>
<h2>购物车</h2>
{/* es6对象展开传属性 */}
<Naviber {...obj}/>
</div>
</div>
)
}
}
  • 子组件
import React, { Component } from 'react'

export default class Naviber extends Component {
render() {
// 子组件接收父组件传过来的props属性
let {title,isShowBtn} = this.props
console.log('父组件传过来的属性(props)',this.props);

return (
<div>
{isShowBtn && <button>返回</button>}
导航栏组件 - {title}
{<button>返回{title}</button>}
</div>
)
}
}

结果展示:

image

属性验证

  • 为了验证传递进来的数据是否符合我们期望的类型或者要求,React提供了PropTypes这个对象用于校验属性的类型,就拿上面的例子来讲,如果上面的父组件给子组件传布尔值的时候,不小心没有使用key={true},而是使用key="true",这就会导致子组件接收到的key是一个字符串而并非一个布尔值,这时我们就可以使用属性验证来验证一下我们从父组件中接收到的props是否为我们期望的类型。

proptypes可以校验的组件类型的属性类型表:

类型 propTypes对应的属性
String(判断是否为字符串型) propTypes.string
Number(判断是否为数值型) propTypes.number
Boolean(判断是否为布尔型) propTypes.bool
Function(判断是否为函数型) propTypes.func
Object(判断是否为对象) propTypes.object
Array(判断是否为数组) propTypes.array
Symbol(判读是否为symbol) propTypes.symbol
Element(React元素) propTypes.element
Node 可被渲染的节点,数字,字符串,React元素或者由这些类型的数据组成的数组) propTypes.node

使用需求:

  1. 安装propTypes
npm i prop-types --save
  1. 在子组件中引入prop-type
//1. 引入验证库
import PropTypes from 'prop-types';
  1. 添加属性验证(两种方法)
/*
1.属性验证(static:表示静态属性,意味着这个类不需要实例化也能读取到里面的属性)
这种方法推荐使用
*/
static propTypes = {//类组件定义内部使用
props属性:myPropTypes.string,//判断是否为字符串
props属性:myPropTypes.bool//判断是否为布尔值
}

// 2. 属性验证二,这种方法不推荐使用
组件名.propTypes = {//组件定义外部使用
props属性:myPropTypes.string,//判断是否为字符串
props属性:myPropTypes.bool//判断是否为布尔值
}

代码展示:

  • 父组件
import React, { Component } from 'react'
import Naviber from './Naviber'
export default class App extends Component {
render() {
// 使用props(属性)传值(父组件通过key=value的形式传值给子组件)类似于Vue的props
return (
<div>
<div>
<h2>首页</h2>
{/* 将title属性和isShowBtn传给子组件 */}
{/* 故意修改错误,将false以字符串的形式传过去给子组件 */}
<Naviber title="home" isShowBtn="false"/>
</div>

<div>
<h2>列表</h2>
<Naviber title="list" isShowBtn={true}/>
</div>

<div>
<h2>购物车</h2>
<Naviber title="cart" isShowBtn={true}/>
</div>
</div>
)
}
}
  • 子组件接收
import React, { Component } from 'react'

// 引入属性验证库(propTypes,引入名字可以随便取)
import myPropTypes from 'prop-types'

export default class Naviber extends Component {

/*
1.属性验证(static:表示静态属性,意味着这个类不需要实例化也能读取到里面的属性)
这种方法推荐使用
*/
static propTypes = {
title:myPropTypes.string,
isShowBtn:myPropTypes.bool
}

render() {
// 子组件接收父组件传过来的props属性
let {title,isShowBtn} = this.props
console.log('父组件传过来的属性(props)',this.props);

return (
<div>
{isShowBtn && <button>返回</button>}
导航栏组件 - {title}
{<button>返回{title}</button>}
</div>
)
}
}

// 2. 属性验证二,这种方法不推荐使用
Naviber.propTypes = {
title:myPropTypes.string,
isShowBtn:myPropTypes.bool
}

结果展示:

image

默认属性

  • defaultProps(默认属性值) 可以为 Class 组件添加默认 props。这一般用于 props 未赋值,但又不能为 null 的情况
  • 注意:defaultProps Class 的属性,也就是静态属性,不是组件实例对象的属性,且在同时有prop-types验证和defaultProps默认属性值时 ,会先处理defaultProps默认属性值,所以即使用户没有输入必传字段,设置了defaultProps默认属性值也不会报错(类型要对应)。

两种写法

// 定义默认属性值方法1,直接在类组件内部定义,这种方法推荐使用
static defaultProps = {//在类组件内部定义
默认属性名:属性值//默认的属性值
}

// 默认值属性二,这种方法不推荐使用
子组件名.defaultProps = {//在类组件外部定义
默认属性名:属性值
}

代码展示:

  • 父组件
import React, { Component } from 'react'
import Naviber from './Naviber'
export default class App extends Component {
render() {
// 使用props(属性)传值(父组件通过key=value的形式传值给子组件)类似于Vue的props
return (
<div>
<div>
<h2>首页</h2>
{/* 将title属性和isShowBtn传给子组件 */}
<Naviber title="home" isShowBtn={false}/>
</div>

<div>
<h2>列表</h2>
{/* 不传isShowBtn属性过去给子组件 */}
<Naviber title="list"/>
</div>

<div>
<h2>购物车</h2>
{/* 不传isShowBtn属性过去给子组件 */}
<Naviber title="cart"/>
</div>
</div>
)
}
}
  • 子组件
import React, { Component } from 'react'

// 引入属性验证库(propTypes,引入名字可以随便取)
import myPropTypes from 'prop-types'

export default class Naviber extends Component {

/*
1.属性验证(static:表示静态属性,意味着这个类不需要实例化也能读取到里面的属性)
这种方法推荐使用
*/
static propTypes = {
title:myPropTypes.string,
isShowBtn:myPropTypes.bool
}

// 默认属性值1,直接在类组件内部定义,这种方法推荐使用
static defaultProps = {
isShowBtn:true
}

render() {
// 子组件接收父组件传过来的props属性
let {title,isShowBtn} = this.props
console.log('父组件传过来的属性(props)',this.props);

return (
<div>
{isShowBtn && <button>返回</button>}
导航栏组件 - {title}
{<button>返回{title}</button>}
</div>
)
}
}

// 2. 属性验证二,这种方法不推荐使用
Naviber.propTypes = {
title:myPropTypes.string,
isShowBtn:myPropTypes.bool
}

// 默认值属性二,这种方法不推荐使用
Naviber.defaultProps = {
isShowBtn:true
}

结果展示:

image