React的Component的构造函数如何真正起作用?

时间:2019-08-12 03:44:04

标签: reactjs constructor es6-class

如果有人能解释以下代码为何起作用,我将不胜感激。

我创建了一个NumberListBase React组件。然后创建另一个名为NumberList的文件,并从NumberListBase派生它。

在两个组件的构造函数中,我有意在调用super()时不将'props'参数传递给父类。

class NumberListBase extends React.Component {
  constructor(props) {
    super();
    Log("NumberListBase.ctor: ", this.props, props);
  }
}
class NumberList extends NumberListBase {
  constructor(props) {
    super();
    Log("NumberList.ctor: ", this.props, props);
  }
  render() {
    const numbers = this.props.numbers;
    const listItems =
          numbers.map((n) => <li key={`${n}`}>{n}</li>);
    return (<ul>{listItems}</ul>);
  }
}

const numbers = [1, 2, 3, 4, 5];

ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

我希望render()会失败,因为this.props将在其中未定义。

我在构造函数中输入的日志消息清楚地表明,NumberListBase构造函数中的'props'参数和'this.props'是'undefined'。

但是,令人惊讶的是,组件正确渲染并显示了数字,这意味着“道具”以某种方式到达了React.Component,而React.Component可以将其放入“ this.props”中!

这是我为这个问题创建的一个Codepen。

https://codepen.io/mansoor-omrani/pen/oKaMXV

我还创建了一个jsfiddle代码段,以测试构造函数在类层次结构中的工作方式。

https://jsfiddle.net/omrani/thnj2zu4/11/

我检查了React.Component源代码以了解如何定义此类。

https://github.com/facebook/react/blob/master/packages/react/src/ReactBaseClasses.js

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;
}

React.Component只是一个简单的函数。我仍然想知道“ this.props”的设置方式,位置和时间!

1 个答案:

答案 0 :(得分:2)

在不带prop的情况下调用super()时,您仍然可以在render和其他方法中访问this.props,因为React在调用构造函数后立即在实例上分配了props。

仅在需要在构造函数中使用super时,才将props传递到props方法中。

他们实施此行为的原因尚不清楚,可能是出于将来的兼容性考虑,因为Robin Pokorny回答了以下问题。

ref:What's the difference between "super()" and "super(props)" in React when using es6 classes?