关于React中的super(props)

读书笔记
原文链接


super

在 JavaScript 中,super 指的是父类(即超类)的构造函数。在下面的例子中,它指向了 React.Component 的实现。super只能用在子类的构造函数之中。

class Checkbox extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isOn: true };
  }
  // ...
}

值得注意的是,在调用父类的构造函数之前,你是不能在 constructor 中使用 this 关键字的。JavaScript 不允许这个行为。这是一种成功陷阱机制

class Checkbox extends React.Component {
  constructor(props) {
    // 🔴  还不能使用 `this`
    super(props);
    // ✅  现在可以了
    this.state = { isOn: true };
  }
  // ...
}

为什么要传入props👇

为了让 React.Component 构造函数能够初始化 this.props,将 props 传入 super 是必须的。

React 源码 :

/**
 * Base class helpers for the updating state of a component.
 */
function Component(props, context, updater) {
  this.props = props;
  this.context = context;
  // If a component has string refs, we will assign a different object later.
  this.refs = emptyObject;
  // We initialize the default updater but the real one gets injected by the
  // renderer.
  this.updater = updater || ReactNoopUpdateQueue;
}

Component.prototype.isReactComponent = {};

为什么不传props,依然能访问到 this.props👇

这当然不是javascript内置的默认逻辑,而是 React 内部做的手脚,在调用构造函数后也立即将 props 赋值到了实例上:

const instance = new YourComponent(props);
instance.props = props;

super() 能代替 super(props) ? 👇

最好不要,虽然 React 会在构造函数执行完毕之后给 this.props 赋值。但在构造函数中 this.props 一直是 undefined

// React 內部
class Component {
  constructor(props) {
    this.props = props;
    // ...
  }
}

// 你的程式碼內部
class Button extends React.Component {
  constructor(props) {
    super(); // 😬 我们忘了传入 props
    console.log(props);      // ✅ {}
    console.log(this.props); // 😬 未定义
  }
  // ...
}

如果在构造函数中调用了其他的内部方法,方法链中用到了this.props,就麻烦了。这是 React 作者建议开发者一定执行 super(props) 的原因。 所以,我们还是乖乖的秉承规范:

class Button extends React.Component {
  constructor(props) {
    super(props); // ✅ 传入 props
    console.log(props);      // ✅ {}
    console.log(this.props); // ✅ {}
  }
  // ...
}