这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战
起步
- github找到react官方代码,clone到自己本地。
- 打开项目,在packages目录下找到react包,然后根据react目录下的package.json文件找到入口文件index.js,此时你可以看到如下所示:
- 可以看到,从
./src/React
文件下导出了我们在开发中用到的API - 接下来,我们进入
./src/React
所在文件 - 在这个文件中可以看到,又是一堆文件引入和导出,总的来说这个文件可以理解成为一个中转站,如下图岁所示:
- 接着,我们找到 createElement 所在文件,先了解它
createElement
- 我们看到,createElement方法接收三个参数,最终返回了一个 ReactElemnt
- 在该函数内部,我们可以看到做了这么几件事:
- 对传入的config进行处理,把除了保留属性外的其他config赋值给props
- 对传入的children进行处理,并将处理后的结果赋值给props.children (此处分了 children为一个节点和多个节点处理)
- 对type.defaultProps进行处理,处理后将属性赋值给props
- 最终调用ReactElement返回一个jsx对象
ReactElement
$$typeof
表示的是组件的类型,例如在源码中有一个检查是否是合法Element的函数,就是根据object.$$typeof === REACT_ELEMENT_TYPE 来判断的- REACT_ELEMENT_TYPE 是在 shared/ReactSymbols 文件中,利用symbol来生成的标记react元素的类型的一个值。源码是这样的
REACT_ELEMENT_TYPE = symbolFor('react.element');
- 上述代码中,
if (__DEV__) {内部的一些操作}
,内部主要是使用Object.deineProperty
来给 element 对象 添加一些属性值 不可修改的 属性
。
isValidElement
- isValidElement 方法用来检验是否是一个reactElement类型
注意: 如果组件是ClassComponent则type是class本身,如果组件是FunctionComponent创建的,则type是这个function,源码中用ClassComponent.prototype.isReactComponent
来区别二者。
注意: class或者function创建的组件一定要首字母大写
,不然后被当成普通节点,type就是字符串。