今天我們來寫乙個自己的renderer,也就是react的渲染器。開始之前,先來了解一下react的三個核心。
先建立乙個檔案,就叫renderer吧,怎麼寫呢,看下react-reconciler的readme.md如下:
import reconciler from
"react-reconciler"
const hostconfig = ;
const myreconcilerinstance = reconciler(hostconfig);
const mycustomrenderer =
};export
default mycustomrenderer
複製**
然後hostconfig怎麼寫呢,官方已經給出了完整的列表,不過我們不需要寫那麼多,先寫出來需要的,如下,先把所有的函式都打上log,看一下呼叫順序:
// 這些是渲染需要的
const hostconfig = ,
getchildhostcontext(...args) ,
getroothostcontext(...args) ,
},prepareforcommit(...args) ,
resetaftercommit(...args) ,
createinstance(...args) ,
},finalizeinitialchildren(...args) ,
shouldsettextcontent(...args) ,
shoulddeprioritizesubtree(...args) ,
createtextinstance(...args) ,
scheduledeferredcallback(...args) ,
canceldeferredcallback(...args) ,
shouldyield(...args) ,
scheduletimeout(...args) ,
canceltimeout(...args) ,
notimeout(...args) ,
now(...arg),
isprimaryrenderer(...args) ,
supportsmutation:true,
}複製**
class
extends
component
increment = () => })}
decrement = () => })}
render() = this.state;
return (
onclick=> - button>
span>
onclick=> + button>
div>)}
}複製**
開啟瀏覽器看一下發現並沒有渲染出任何東西,開啟console,這些函式的呼叫順序如下圖,好的,那我們開始寫這些函式:
// rootcontainerinstance 根節點 我們這裡就是div#root
getroothostcontext(rootcontainerinstance)
}複製**
/**
* parenthostcontext 從上一級節點傳遞過來的上下文
* type 當前節點的nodetype
* rootcontainerinstance 根節點
*/ getchildhostcontext(parenthostcontext, type, rootcontainerinstance)
} 複製**
/*
* type 當前節點的nodetype
* props 要賦予當前節點的屬性
*/shouldsettextcontent(type, props) ,
複製**
/**
* type 當前節點的nodetype
* newprops 傳遞給當前節點的屬性
* rootcontainerinstance 根節點
* currenthostcontext 從上級節點傳遞下來的上下文
* workinprogress 當前這個dom節點對應的fiber節點
*/ createinstance(type, newprops, rootcontainerinstance, currenthostcontext, workinprogress) else
if (key === 'style') else
if (key.startswith('on')) else
if (key === 'children')
} else
}return element
},複製**
/**
* domelement 當前已經生成的dom節點
* type nodetype
* props 屬性
* rootcontainerinstance 根節點
* hostcontext 上下級傳遞過來的上下文
*/ finalizeinitialchildren(domelement, type, props, rootcontainerinstance, hostcontext) ,
複製**
/**
* parentinstance 上一級節點
* child 子節點
*/ }複製**
// rootcontainerinstance 根節點
preparefomcommit(rootcontainerinstance){}
複製**
// container 我們的根節點
// child 已經生成的節點
}複製**
resetaftercommit(){}
複製**
好了,現在我們的初次渲染已經大功告成了。
然後我畫了一張比較醜陋的流程圖:
/**
* domelement 當前遍歷的dom節點
* type nodetype
* oldprops 舊的屬性
* newprops 新屬性
* rootcontainerinstance 根節點
* hostcontext 從上一級節點傳遞下來的上下文
*/ prepareupdate(domelement, type, oldprops, newprops, rootcontainerinstance, hostcontext)
} else
};return updatepayload
}複製**
/**
* domelement 對應的dom節點
* updatepayload 我們剛才決定返回的更新
* type nodetype
* oldprops 舊的屬性
* newprops 新屬性
* internalinstancehandle 當前dom節點對應的fiber節點
*/ commitupdate(domelement, updatepayload, type, oldprops, newprops, internalinstancehandle) else
if (propkey === 'children') else
}},複製**
woola!更新也完成了。
同樣也畫了一張醜陋的流程圖:
**有點多,各位看官辛苦!本文所有**均可在此處找到
參考:
了解一下NTLM
ntlm 在客戶機與伺服器之間提供身份認證的安全包。ntlm 身份驗證協議 是 質詢 應答身份驗證協議,是windows nt 4.0 及其早期版本中用於網路身份驗證的預設協議。windows 2000 中仍然支援該協議,但它不再是預設的。ntlm身份驗證過程 ntlm 是用於 windows nt...
了解一下 display flex
一 display flex flex 是flexuble box的縮寫,意為 彈性盒子 用來為盒狀模型提供最大的靈活性.任何乙個容器都可以指定為flex布局.box 行內元素也可以使用flex布局.box webkit核心的瀏覽器,必須加上 webkit box 注意為父級設計flex布局以後,子...
指標了解一下
在c語言中,我們會頻繁的使用指標,那麼什麼是指標?首先我們來看一段 include int main 假如建立的變數a的位址為0x0000ff11,那麼指標變數指向變數a,存放的是變數a的位址。總結 指標就是位址,指標變數是變數,指標變數是用來儲存位址的變數。存放在指標變數中的值都會被當做位址來處理...