React原始碼解讀 元件的實現

2021-08-30 15:54:26 字數 4036 閱讀 3068

react使用也有一段時間了,大家對這個框架褒獎有加,但是它究竟好在**呢? 讓我們結合它的原始碼,**一二!(當前原始碼為react16,讀者要對react有一定的了解)

[上傳中...(image-45230e-1541081363064-20)]

根據react官網上的例子,快速構建react專案

npm start

複製**

import react,  from 'react';

import logo from './logo.svg';

render()

}複製**

[上傳中...(image-a11e19-1541081363064-19)]

es6 引入了一種新的原始資料型別symbol,表示獨一無二的值。有興趣的同學可以去阮一峰老師的es6入門詳細了解一下

上面有我們很熟悉的props,ref,key,我們稍微修改一下console,看看有什麼變化。

複製**

[上傳中...(image-6f199-1541081363064-18)]

可以看到,props,key都發生了變化,值就是我們賦予的值,props中巢狀了children屬性。可是為什麼我們嵌入的是div,實際上卻是乙個物件呢?

/node_modules/react

[上傳中...(image-959ff4-1541081363064-17)]

首先開啟index.js

'use strict';

if (process.env.node_env === 'production') else

複製**

[上傳中...(image-3ba56f-1541081363064-16)]

接著找到component: component方法,

function component(props, context, updater) 

component.prototype.isreactcomponent = {};

component.prototype.setstate = function (partialstate, callback) ;

component.prototype.forceupdate = function (callback) ;

複製**

上面就是一些簡單的建構函式,也可以看到,我們常用的setstate是定義在原型上的2個方法。

[上傳中...(image-d3d53c-1541081363064-15)]

到此為止了嗎?這看了等於沒看啊,究竟元件是怎麼變成div的?render嗎? 可是全域性搜尋,也沒有乙個function是render啊。

原來,我們的jsx語法會被babel編譯的。

[上傳中...(image-df2f00-1541081363064-14)]

這下清楚了,還用到了react.createelement

createelement: createelementwithvalidation,

複製**

通過createelementwithvalidation,

function createelementwithvalidation(type, props, children) 

複製**

可以看到,return了乙個element,這個element又是繼承自createelement,接著往下找:

function createelement(type, config, children) ;

var key = null;

var ref = null;

var self = null;

var source = null;

······

return reactelement(type, key, ref, self, source, reactcurrentowner.current, props);

}複製**

這裡又返回了乙個reactelement方法,再順著往下找:

var reactelement = function (type, key, ref, self, source, owner, props) ;

······

return element;

};複製**

[上傳中...(image-d07b-1541081363063-13)]

[上傳中...(image-84a3a-1541081363063-12)]

react.createelement 、 createelementwithvalidation 、 createelement 、 reactelement,通過這些方法,我們用class宣告的react元件在變成真實dom之前都是reactelement型別的js物件

createelementwithvalidation:

[上傳中...(image-707490-1541081363063-11)]

[上傳中...(image-af4fe-1541081363063-10)]

[上傳中...(image-2fc1e7-1541081363063-9)]

createelement

[上傳中...(image-4cc7fe-1541081363063-8)]

[上傳中...(image-455952-1541081363063-7)]

[上傳中...(image-9da872-1541081363063-6)]

[上傳中...(image-b00189-1541081363063-5)]

reactelement

reactelement就比較簡單了,建立乙個element物件,引數裡的type、key、ref、props、等放進去,然後return了。最後呼叫object.freeze使物件不可再改變。

[上傳中...(image-4a8779-1541081363063-4)]

複製**

我們接著用babel編譯一下:

[上傳中...(image-572eb-1541081363063-3)]

原來reactdom.render呼叫的是render方法,一樣,找暴露出來的介面。

var reactdom = ,

······

};複製**

它返回的是乙個legacyrendersubtreeintocontainer方法,這次我們直接打上console.log

[上傳中...(image-d4de88-1541081363063-2)]

這是列印出來的結果,

[上傳中...(image-303c7d-1541081363063-1)]

legacyrendersubtreeintocontainer 這個方法除主要做了兩件事:

while (rootsibling = container.lastchild) 

}container.removechild(rootsibling);

}複製**

[上傳中...(image-74690b-1541081363063-0)]

原始碼暫時唯讀到了這裡,關於react16.1~3的新功能,以及新的生命週期的使用和原理、fiber究竟是什麼,我們將在後續文章接著介紹。

React原始碼學習 建立元件過程(2)

當使用react建立元件時,首先會呼叫instantiatereactcomponent,這是初始化元件的入口函式,它通過判斷node型別來區分不同元件的入口。1.當node為空時,說明node不存在,則初始化空元件reactemptycomponent.create instantiatereac...

SDWebImage的原始碼解讀

sdwebimage共有17個oc檔案以及乙個多餘的標頭檔案,下面將會按照順序乙個乙個進行檔案的解讀 本人學藝不精,如果有不對的地方歡迎指出,有些細節的東西我也不算很理解,寫下這邊也算是方便以後用到的時候回顧 1.imagecontexttype 檔案 主要提供識別資料的格式,是nsdata的分類,...

OkHttp的原始碼解讀

最近這幾天在研究okhttp的原始碼,就順便整理了一些文件。retrofit okhttpcall原始碼解讀 okhttp之dispatcher okhttp之getresponsewithinterceptorchain 一 okhttp之getresponsewithinterceptorcha...