本文基于 React v16.8.6
以下是使用三种 Component 创建的一个组件
import React, {
Component, PureComponent } from 'react';
// function Component
function FuncComp() {
return <div>FuncComp</div>
}
// Component
class Comp extends Component {
render() {
return (
<div>
component
</div>
);
}
}
// Pure Component
class PureComp extends PureComponent {
render() {
return (
<div>
Pure Component
</div>
);
}
}
console.log(<FuncComp />);
console.log(<Comp />);
console.log(<PureComp />);
export default class extends Component {
render() {
return (
<div>
<FuncComp />
<Comp />
<PureComp />
</div>
);
}
}
生成元素的差异
经过 React.createElement
处理之后,三个组件的区别就是 type 不一样了
type 是刚才定义的 function 或者 class
__proto__
和 prototype
看不懂可以看下这篇文章 https://www.zhihu.com/question/34183746 js 中 __proto__
和 prototype
的区别和关系
Component
/**
* 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.
// ref 有好几个方式创建,字符串的不讲了,一般都是通过传入一个函数来给一个变量赋值 ref 的
// ref={el => this.el = el} 这种方式最推荐
// 当然还有种方式是通过 React.createRef 创建一个 ref 变量,然后这样使用
// this.el = React.createRef()
// ref={this.el}
// 关于 React.createRef 就阅读 ReactCreateRef.js 文件了
this.refs = emptyObject;
// We initialize the default updater but the real one gets injected by the
// renderer.
// 如果你在组件中打印 this 的话,可能看到过 updater 这个属性
// 有兴趣可以去看看 ReactNoopUpdateQueue 中的内容,虽然没几个 API,并且也基本没啥用,都是用来报警告的
this.updater = updater || ReactNoopUpdateQueue;
}
Component.prototype.isReactComponent = {
};
/**
* Sets a subset of the state. Always use this to mutate
* state. You should treat `this.state` as immutable.
*
* There is no guarantee that `this.state` will be immediately updated, so
* accessing `this.state` after calling this method may return the old value.
*
* There is no guarantee that calls to `setState` will run synchronously,
* as they may eventually be batched together. You can provide an optional
* callback that will be executed when the call to setState is actually
* completed.
*
* When a function is provided to setState, it will be called at some point in
* the future (not synchronously). It will be called with the up to date
* component arguments (state, props, context). These values can be different
* from this.* because your function may be called after receiveProps but before
* shouldComponentUpdate, and this new state, props, and context will not yet be
* assigned to this.
*
* @param {object|function} partialState Next partial state or function to
* produce next partial state to be merged with current state.
* @param {?function} callback Called after state is updated.
* @final
* @protected
*/
// 我们在组件中调用 setState 其实就是调用到这里了
// 用法不说了,如果不清楚的把上面的注释和相应的文档看一下就行
// 一开始以为 setState 一大堆逻辑,结果就是调用了 updater 里的方法
// 所以 updater 还是个蛮重要的东西
Component.prototype.setState = function (partialState, callback) {
(function () {
if (!(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null)) {
{
thro