React源码解读(一)
前言
这两周面试了几个人,虽然是一面,问的不深,但是给我的感觉都是对React了解的比较浅,稍微往深一点问基本都是回答得很宽泛,答不到点子上,虽然有引导他们去思考但是由于react的理解很片面所以基本也答不出来,因此就来写个我对于react的源码的解读,我将从项目结构入手分析React源码。
ReactDOM.render() (github上ReactDOM.js 672行)
一个React项目的最外层就是一个指定的DOM节点,通过render函数将我们需要渲染的组件插入到指定DOM节点中来实现视图,来看看render到底做了什么。
源码如下:
1 | render( |
由于render方法在React生命周期各个时期中有着不同的作用,因此render中分了首次挂载和更新两种情况。
首次挂载时,通过legacyCreateRootFromDOMContainer生成了一个root对象,并将这个root对象赋给了DOM容器,下面来看看legacyCreateRootFromDOMContainer
。
1 | function legacyCreateRootFromDOMContainer( |
可以看出来它干了两件事情,一个是当不应该注水的时候清空了container的子节点(应该就是非ssr的情况下),还有一件事情就是返回了一个新的ReactRoot对象。问题又来了这个ReactRoot又是个什么东西。
1 | function ReactRoot( |
从上面可以看出来这个ReactRoot是个构造函数,它有render等方法,上述的root则会去执行render方法并返回一个ReactWork对象,那接下来就是这个updateContainer到底干了些什么了。通过上面的层层扒皮,无论怎样判断,最终都会到render方法和legacy_renderSubtreeIntoContainer方法中,而这两个方法的核心就是updateContainer,无非就是传不传父组件而已。
1 | export function updateContainer( |
updateContainer传入的参数有虚拟dom对象树、之前造出来的root中和fiber相关的_internalRoot、父组件、回调函数。