在经过对state的学习后,可以理解state为组件内部数据的处理,也就是说是一些静态数据的处理。
但在我们实际的业务场景中,一般都是服务端返回的数据,渲染这些数据该怎么办呢?
props可以来解决这个问题。这也是React设计props的初衷。
props的学习相对state来说,要简单些。
一、props的基础使用
//创建组件
class Person extends React.Component{
render(){
console.log(this)
return (
<ul>
<li>姓名:{this.props.name}</li>
<li>性别: {this.props.sex}</li>
<li>年龄:{this.props.age}</li>
</ul>
)
}
}
//渲染组件
ReactDOM.render(<Person name="Tom" sex="男" age="20"/>,document.getElementById("test"))
ReactDOM.render(<Person name="Lily" sex="女" age="18"/>,document.getElementById("test1"))
const p ={name:'lucy',sex:'女',age:17}
// ReactDOM.render(<Person name={p.name} sex={p.sex} age={p.age}/>,document.getElementById("test2"))
//此处展开运算符 不是复制对象 仅用于标签属性的使用
//当存在babel翻译和React的情况下使用。
//批量传递属性
ReactDOM.render(<Person {...p}/>,document.getElementById("test2"))
二、对props的限制
要对props进行限制,在React15.5.5版本前是通过React对象本身上去做处理,但考虑到这样做实际上会对React的体积产生影响,不管用不用到限制,都会挂载到React的对象上。所以在之后的版本,对于props的限制,就抽离出了一个库,叫prop-types。
所以在开始代码前,需要先准备prop-types.js
<!-- 引入prop-types,限制组件props-->
<script src="js/prop-types.js"></script>
对prop的限制方法很简单,如下:
//给组件props添加限制
Person.propTypes={
name:PropTypes.string.isRequired,//限制name为必传,且为字符串
sex:PropTypes.string,//限制sex为字符串
age:PropTypes.number,//限制age为数值
speak:PropTypes.func//限制speak为方法,注意方法写法为func,不可为function
}
除了上述的限制规则之外,还有很多的规则,可以到文档中查看。
在具体业务中,可能会涉及到一些默认值的设置。
//给组件props添加默认值
Person.defaultProps={
sex:'男',
age:18
}
三、props的简写方式
和state一样,props也有简写方式,如下:
class Person extends React.Component{
//构造器是否接收props,是否传递给super,取决于:是否希望在构造器中通过this访问props
//如果不需要通过this访问,直接使用props,可以不用向super传递
constructor(props) {
super(props);
console.log(this.props)
console.log(props)
}
//给类自身添加属性 以赋值形式添加propTypes defaultProps
//需要在前边添加 static 属性 表明它是静态属性
//给组件props添加限制
static propTypes={
name:PropTypes.string.isRequired,//限制name为必传,且为字符串
sex:PropTypes.string,//限制sex为字符串
age:PropTypes.number,//限制age为数值
speak:PropTypes.func//限制speak为方法,注意方法写法为func,不可为function
}
//给组件props添加默认值
static defaultProps={
sex:'男',
age:18
}
render(){
// console.log(this)
let {name,sex,age} = this.props
// this.props.name = 'jack' //这行会报错,因为props是只读的
return (
<ul>
<li>姓名:{name}</li>
<li>性别: {sex}</li>
<li>年龄:{age}</li>
</ul>
)
}
}
四、在函数式组件使用props
之前,我们说过函数式组件的种种不足,不可以使用state,refs(最新版本可以结合hooks使用)。但函数式组件可以使用props,原因就是函数式组件可以传参。如下:
//创建组件
function Person(props) {
let {name, sex, age} = props
return (
<ul>
<li>姓名:{name}</li>
<li>性别: {sex}</li>
<li>年龄:{age}</li>
</ul>
)
}
Person.propTypes = {
name: PropTypes.string.isRequired,//限制name为必传,且为字符串
sex: PropTypes.string,//限制sex为字符串
age: PropTypes.number,//限制age为数值
speak: PropTypes.func//限制speak为方法,注意方法写法为func,不可为function
}
//给组件props添加默认值
Person.defaultProps = {
sex: '男',
age: 18
}
//渲染组件
const p = {name: 'lucy', sex: '女', age: 17}
ReactDOM.render(<Person {...p}/>, document.getElementById("test2"))
五、总结
一、理解
1、每个组件对象都会有props
(properties的简写)属性。
2、足见标签的所有属性都保存在props中
二、作用
1、通过标签属性从组件外向组件内传递变化的数据。
2、注意:组件内部不要修改props数据,是只读的。
三、编码操作
1、内部读取某个属性值
<span class="italic">
this.props.name
</span>
2、对props中的属性值进行类型限制和必要性限制
(1) 第一种方式(React v15.5开始已弃用)
Person.proTypes={
name:React.ProTypes.string.isRequired,
age:React.ProTypes.number
}
(2) 第二种方式
使用prop-types
库进行限制(需要引入prop-types库)
Person.proTypes={
name:ProTypes.string.isRequired,
age:ProTypes.number
}
3、扩展属性:将对象的所有属性通过props传递
<Person {...person}/>
4、默认属性值
Person.defaultProps={
age:18,
sex:'男'
}
5、组件类的构造函数
constructor(props){
super(props)
console.log(props)
}