经过之前课程的学习,我们对props
有了一定的了解,也知道了该如何简写,但是大家是否有一些疑惑呢?你看我们自从state
的简写之后好像就再也没有写过构造器方法啊,那么我们都没用构造器方法,为什么组件还能够正常接收到我们传入的props
呢?这节课我们就来说一说
回顾
在学习新的内容之前我们先来对上节课内容来做一个简单的回顾
propsTypes
和defaultProps
必须是组件类自身的属性,不是实例对象的属性- 用
static
关键字给类自身添加属性 props
是只读的
以上就是上节课的内容,接下来我们开始正式讨论一下,构造器和props
构造器与props
几个现象
我们先来回顾一下我们的代码
class Person extends React.Component { static propTypes = { name: PropTypes.string.isRequired, gender: PropTypes.string, age: PropTypes.number }; static defaultProps = { gender: "男", age: 18 } render() { const { name, age, gender } = this.props; return ( <ul> <li>姓名:{name}</li> <li>性别:{gender}</li> <li>年龄:{age + 1}</li> </ul> ); } } ReactDOM.render( <Person name="jingxun" />, document.getElementById("test") );
我们之前是不是根本没写构造器?只是做了对props
的限制,然后渲染,渲染的时候我就只传了name
其余的两个属性全都是默认值。
那么现在我先把构造器还原回来,按照官网的写法:
class Person extends React.Component { constructor(props) { console.log(props); super(props); } static propTypes = {...}; static defaultProps = {...} render() {return ...} }
按照官网的写法我是不是要在构造器中接收props
然后在传给super
啊?,我们看一下构造器中打印出来的props
是什么:
可能有人要说了,我只传了name
啊,但是这里怎么有gender
和age
啊?这是不是因为我们给了默认值?所以才会出现这种情况。
但是有人问了,如果我不把props
传给super
行不行呢?我就只是调用一下super()
但是不传参:
class Person extends React.Component { constructor(props) { console.log(props); super(); } ... }
我们看一下:
没有问题,我也接收到了,然后可能有人就开始发散思维了,那我构造器我也不打印props
了,我就压根不接收,我就单单调一下super()
又会怎么样?那试试呗:
class Person extends React.Component { constructor() {super();} ... }
看一下效果:
页面也正常渲染,也没有报错。但是大家想一想,我都可以不写构造器,我还在乎什么接不接,传不传的问题啊?
探讨
但是我们探讨一下几个问题:
- 我们用构造器接了
props
之后,传给super
和不传给super
有啥区别呢? react
类组件中的构造器到底是什么作用呢?
我们先来看一下官方文档的解释:
官方给的解释很明白了,通常来说只有这两个场景才会用到构造器。这两个场景我们可是都用过了。
但是可能有人要问,第二个是啥啊?我们什么时候用过?
我们回想当初解决点击事件类方法中this
指向丢失问题的时候不就是在构造器中写了this.method = this.method.bind(this)
这种场景嘛,这个就是官网说的第二个场景。
那么我们学了简写state
之后我们这两个场景都用不上构造器了啊?那么构造器可以说是没有存在的意义的。
但是又有人问了,我接收props
传给super
和不传的区别是啥呢?我传了之后有什么影响呢?官方也给了答案:
什么意思呢?首先,我们如果不写构造器对我们的代码有影响吗?没有任何影响。但是如果我在一个类的子类里写了构造器,按照类的基础语法,我是不是必须要调super
?但是我调super
时候传props
和不传有吗区别?官方给的解释就是如果不传,那么在构造器中你使用this.props
可能会出现undefined
的情况。我们来测一下:
class Person extends React.Component { constructor(props) { super(props); console.log("constructor:",this.props); } ... }
我们看上面这段代码,我们接了props
也传给了super
,那我们在构造器中打印一下this.props
是不是输出正常啊?那么接下来我只接但是不传给super
class Person extends React.Component { constructor(props) { super(); console.log("constructor:",this.props); } ... }
现在再打印一下
这次输出的就是undefined
那我们来总结一下,我们的类组件能不能不写构造器?可以,但是如果我写了构造器,而且还需要在构造器中来通过this
来取到props
,那么就必须接收props
并且传给super
。
但是大家想一下,如果我们真的要在构造器里面取props
中的数据来做一些处理和判断的话,为啥要用this.props
啊?我构造器都接收到了直接拿来用呗。所以说真的没必要。
那么以上便是我们读构造器和props
之间的联系的一些探讨
总结
- 类组件不写构造器完全可以,而且能不写就尽量不写
- 构造器中
props
传给super
和不传给super
的区别就是在构造器中能否通过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/constructor_props/