React 的 Component 的构造函数究竟是如何工作的?
How does React's Component's constructor really work?
如果有人能解释为什么下面的代码有效,我将不胜感激。
我创建了一个 NumberListBase React 组件。然后创建了另一个,命名为 NumberList 并派生自 NumberListBase。
在这两个组件的构造函数中,我故意在调用 super() 时不将 'props' 参数传递给父 class。
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 在其中未定义。
我在构造函数中输入的日志消息清楚地表明 'props' 参数和 'this.props' 在 NumberListBase 构造函数中是 'undefined'。
但是,令人惊讶的是,组件正确呈现并显示了数字,这意味着 'props' 以某种方式到达 React.Component,并且 React.Component 可以将其放入 'this.props'!
这是我为这个问题创建的代码笔。
https://codepen.io/mansoor-omrani/pen/oKaMXV
我还创建了一个 jsfiddle 片段来测试构造函数如何在 class 层次结构中工作。
https://jsfiddle.net/omrani/thnj2zu4/11/
我检查了 React.Component 源代码以了解这个 class 是如何定义的。
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' 的设置方式、地点和时间!
当你在没有 props 的情况下调用 super() 时,你仍然可以在渲染和其他方法中访问 this.props,因为 React 在调用你的构造函数后立即在实例上分配 props。
只有当我们需要在构造函数中使用 props
时,我们才将 props 传递给 super
方法。
他们实现此行为的原因尚不清楚,可能是出于将来的兼容性原因,正如 Robin Pokorny 对以下问题的回答。
参考:
如果有人能解释为什么下面的代码有效,我将不胜感激。
我创建了一个 NumberListBase React 组件。然后创建了另一个,命名为 NumberList 并派生自 NumberListBase。
在这两个组件的构造函数中,我故意在调用 super() 时不将 'props' 参数传递给父 class。
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 在其中未定义。
我在构造函数中输入的日志消息清楚地表明 'props' 参数和 'this.props' 在 NumberListBase 构造函数中是 'undefined'。
但是,令人惊讶的是,组件正确呈现并显示了数字,这意味着 'props' 以某种方式到达 React.Component,并且 React.Component 可以将其放入 'this.props'!
这是我为这个问题创建的代码笔。
https://codepen.io/mansoor-omrani/pen/oKaMXV
我还创建了一个 jsfiddle 片段来测试构造函数如何在 class 层次结构中工作。
https://jsfiddle.net/omrani/thnj2zu4/11/
我检查了 React.Component 源代码以了解这个 class 是如何定义的。
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' 的设置方式、地点和时间!
当你在没有 props 的情况下调用 super() 时,你仍然可以在渲染和其他方法中访问 this.props,因为 React 在调用你的构造函数后立即在实例上分配 props。
只有当我们需要在构造函数中使用 props
时,我们才将 props 传递给 super
方法。
他们实现此行为的原因尚不清楚,可能是出于将来的兼容性原因,正如 Robin Pokorny 对以下问题的回答。
参考: