前一节课我们学完了react
组件的三大属性之一的state
,并且对state
做了一个阶段性的总结。虽然总结的内容很少,但是每一点的展开的细节加到一起就是之前的7
个课时的内容。那么今天这节课我们开始学习第二个属性:props
。
案例需求
我们学习props
先通过一个案例来引入我们要学的东西。我不喜欢直接去讲一些枯燥的理论,我们先做点什么出来。那我们的需求是什么呢?
我们定义一个用来显示人员信息的组件,要求:
- 姓名为必须指定,且为字符串类型
- 性别如果没有指定,默认为男
- 年龄必须指定,且为数字类型
效果:
分析
我们来分析一下这个需求,我们上半部分和下半部分的内容是不是很相似,都是展示了姓名,性别和年龄。而且每一个人都是一个列表的形式,都是<ul><li>
的标签。
实现
那么好,这个我们分析完了之后那就开始做吧。我们先别管那么多,先来实现,等我们实现了之后再来谈优化和问题解决:
class Person extends React.Component { render() { return ( <ul> <li>姓名: 景珣</li> <li>性别: 男</li> <li>年龄: 18</li> </ul> ); } } ReactDOM.render(<Person />, document.getElementById("test"));
我们来看一下上面的代码:
- 创建组件
- 在组件中添加
render
方法 - 在
render
方法中返回虚拟DOM
,我这里先暂时写死了 - 渲染组件到页面
来看一下效果:
一切正常,页面出来了。
页面动态化
那么我现在的信息都是写死的,可是我想让这个页面动态起来该怎么办?
用state
行不行
经过我们前面的学习,基本上大家马上下意识地就会说,我用state
啊。state
的用途不就是存放数据的嘛,然后我们通过更新数据来驱动页面重新渲染。
class Person extends React.Component { state = { name:"jingxun", age: 18, gender: "男" } render() { return ( <ul> <li>姓名: {this.state.name}</li> <li>性别: {this.state.gender}</li> <li>年龄: {this.state.age}</li> </ul> ); } } ReactDOM.render(<Person />, document.getElementById("test"));
那这样写行不行呢?我们来看一下:
是不是也正常渲染出来了啊?但是如果这样的话我是不是要在组件内部就把state
定义好初始化好啊?但是如果我现在的需求要从组件外往组件里传入这些信息的话怎么办?这样我没法去初始化state
了啊。因为我们之前就说了,我们初始化state
直接用赋值语句来写了,这种方法只能在组件内部写死,没法接收外部参数啊,所以说我们不能在使用state
了。
有些朋友可能说,我还是没太理解,那比如这么说把,下面这段代码:
class Person extends React.Component { state = { name:"jingxun", age: 18, gender: "男" } render() { return ( <ul> <li>姓名: {this.state.name}</li> <li>性别: {this.state.gender}</li> <li>年龄: {this.state.age}</li> </ul> ); } } ReactDOM.render(<Person />, document.getElementById("test1")); ReactDOM.render(<Person />, document.getElementById("test2"));
这里我渲染了两个容器,也都是用了state
,但是我们得到的效果是什么呢?
你看,即便我们用了state
,state
也确实是为了来做动态渲染的,但是我们页面上展示的还是两个一模一样的容器,那有人说我们写一个新的组件来放第二个容器。那我们组件话不就没有意义了嘛,一个组件只能给一个容器用得话我们的复用率为 0 啊。
那么我们的预期是不是就像函数一样,我们传入什么数据,就让react
来渲染什么啊?那我们是不是就想我们能不能在ReactDOM.render(<Person />, document.getElementById("test1"));
这一步我们做点什么文章来让这两个容器来渲染点不一样的东西?
不能用state
该用什么
我们刚刚说要在如果在ReactDOM.render(<Person />, document.getElementById("test1"));
这一步做文章,但是如果能从这里传入数据的话,我们的state
接收不到,那这怎么办呢?有人说我们借助构造器,用构造器来接收我们就可以用state
了
那么好,我们回想一下,react
中的构造器是怎么写的?
class Person extends React.Component { constructor(props) { super(props); this.state = {}; } }
这是什么意思?构造器接收到的其实是props
,有人又说了,那我从props
把state
的数据拿出来,然后再赋给state
,那不是多此一举吗?
我们本身就有props
属性啊,这不是我们react
组件的三大属性之一嘛。那直接用props
不就可以了嘛。那么好,我们怎么使用props
呢?
props
的使用
现在我们知道可以用props
来写我们的需求,但是我们怎么使用呢?是不是也y用this
来调用呢?我们先来看一下render
方法中的this
:
render() { console.log(this); return ...; }
打印一下this
:
首先,这里的this
指向的是谁?是不是Person
的实例对象?那么Person
的实例对象上有什么?是不是有props
在?而且props
是一个空对象,因为我们确实没有传入任何东西进去。
其实props
真的比state
要简单得多,state
还需要我们亲自来写里面的值,但是props
不需要,因为props
是我们传入进去的数据,这个数据在实际开发中是来自我们后端接口的,当然目前我们还没到那一步,我们先自己mock
一部分然后传进来就行了。
但是怎么传呢?我们说了半天了要传数据传数据,但是到底要怎么传可是一句都没有提。先别着急,我们来思考一个问题。
HTML
标签是不是可以写标签属性?比如我们的容器,<div id="test"></div>
我们这个标签的标签名叫div
,里面有一个id
属性,那么这个属性的属性名叫id
,属性值是test
,那这个是不是类似于一对key-value
?id
是key
,test
就是value
?那么HTML
标签本身就可以写很多组key-value
的组合。
我们再回头看一下渲染组件那一步,我们写的组件是以什么形式传进去的?是不是也是一个标签?那么这个标签能不能也写这种key-value
的组合属性呢?那我们试试呗:
class Person extends React.Component {...} ReactDOM.render(<Person name="jingxun"/>, document.getElementById("test1"));
这样一写,我们会得到什么结果呢?
我们从图上来看,是不是我们已经接收到name
这个属性了?而且还存放到了props
中,也就是说,当我们想上面那段代码那么写的话react
在渲染组件的时候就会把name
作为key
,name
属性的值作为value
传入了组件存放到了props
中了。
那么以此类推,我们直接在标签里面来写我们要传的属性就行了啊,那么数据也传进去了,我们在render
方法中就可以通过this
来调用props
了,就想调用state
一样:
class Person extends React.Component { state = { name:"jingxun", age: 18, gender: "男" } render() { return ( <ul> <li>姓名: {this.props.name}</li> <li>性别: {this.props.gender}</li> <li>年龄: {this.props.age}</li> </ul> ); } } ReactDOM.render( <Person name="jingxun" age="18" gender="男"/>, document.getElementById("test1") );
这样的话我们再来看一下效果:
信息也出来了,但是这里的优势就在于我能在组件标签那一步动态地去修改props
的内容。而且再回到刚才我们说的
class Person extends React.Component {...} ReactDOM.render( <Person name="jingxun" age="18" gender="男"/>, document.getElementById("test1") ); ReactDOM.render( <Person name="dschow" age="18" gender="女"/>, document.getElementById("test2") );
那这一步我们页面是什么样子呢?
这一次,我渲染出来的就是两个完全不一样的信息,这样的话东西都是动态地传入标签的。
以上就是我们props
最基本的使用
总结
props
是一个对象props
是通过外面往组件内传入数据props
在组件的实例对象上可以通过this
调用props
可以在组件标签处通过标签属性传入
Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.
Link of this article:https://work.lynchow.com/article/props_basic/