经过之前课程的学习,我们对props有了一定的了解,也知道了该如何简写,但是大家是否有一些疑惑呢?你看我们自从state的简写之后好像就再也没有写过构造器方法啊,那么我们都没用构造器方法,为什么组件还能够正常接收到我们传入的props呢?这节课我们就来说一说

回顾

在学习新的内容之前我们先来对上节课内容来做一个简单的回顾

  • propsTypesdefaultProps必须是组件类自身的属性,不是实例对象的属性
  • 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是什么:

image-20211221153306566

可能有人要说了,我只传了name啊,但是这里怎么有genderage啊?这是不是因为我们给了默认值?所以才会出现这种情况。

但是有人问了,如果我不把props传给super行不行呢?我就只是调用一下super()但是不传参:

class Person extends React.Component {
  constructor(props) {
    console.log(props);
    super();
  }
  ...
}

我们看一下:

image-20211221153638276

没有问题,我也接收到了,然后可能有人就开始发散思维了,那我构造器我也不打印props了,我就压根不接收,我就单单调一下super()又会怎么样?那试试呗:

class Person extends React.Component {
  constructor() {super();}
  ...
}

看一下效果:

image-20211221153917693

页面也正常渲染,也没有报错。但是大家想一想,我都可以不写构造器,我还在乎什么接不接,传不传的问题啊?

探讨

但是我们探讨一下几个问题:

  1. 我们用构造器接了props之后,传给super和不传给super有啥区别呢?
  2. react类组件中的构造器到底是什么作用呢?

我们先来看一下官方文档的解释:

image-20211221154500150

官方给的解释很明白了,通常来说只有这两个场景才会用到构造器。这两个场景我们可是都用过了。

但是可能有人要问,第二个是啥啊?我们什么时候用过?

我们回想当初解决点击事件类方法中this指向丢失问题的时候不就是在构造器中写了this.method = this.method.bind(this)这种场景嘛,这个就是官网说的第二个场景。

那么我们学了简写state之后我们这两个场景都用不上构造器了啊?那么构造器可以说是没有存在的意义的。

但是又有人问了,我接收props传给super和不传的区别是啥呢?我传了之后有什么影响呢?官方也给了答案:

image-20211221155150492

什么意思呢?首先,我们如果不写构造器对我们的代码有影响吗?没有任何影响。但是如果我在一个类的子类里写了构造器,按照类的基础语法,我是不是必须要调super?但是我调super时候传props和不传有吗区别?官方给的解释就是如果不传,那么在构造器中你使用this.props可能会出现undefined的情况。我们来测一下:

class Person extends React.Component {
  constructor(props) {
    super(props);
    console.log("constructor:",this.props);
  }
  ...
}

我们看上面这段代码,我们接了props也传给了super,那我们在构造器中打印一下this.props

image-20211221155901404

是不是输出正常啊?那么接下来我只接但是不传给super

class Person extends React.Component {
  constructor(props) {
    super();
    console.log("constructor:",this.props);
  }
  ...
}

现在再打印一下

image-20211221160030800

这次输出的就是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/