±à¼ÍƼö: |
±¾ÎÄÖ÷Òª´ÓjsxÈëÊÖ£¬ÊÖдһ¸ö¼òÒ×°æµÄReact£¬´Ó¶øÉîÈëÀí½âReactµÄÔÀí·½Ãæ½øÐнéÉÜ¡£
±¾ÎÄÀ´×ÔÓÚǰ¶Ë°áÔ˹¤
,ÓÉ»ðÁú¹ûÈí¼þAlice±à¼ÍƼö¡£ |
|
JSXºÍcreatElement
ÒÔǰÎÒÃÇдReactÒªÖ§³ÖJSX»¹ÐèÒªÒ»¸ö¿â½ÐJSXTransformer.js£¬ºóÀ´JSXµÄת»»¹¤×÷¶¼¼¯³Éµ½ÁËbabelÀïÃæÁË£¬babel»¹ÌṩÁËÔÚÏßÔ¤ÀÀµÄ¹¦ÄÜ£¬¿ÉÒÔ¿´µ½×ª»»ºóµÄЧ¹û£¬±ÈÈçÏÂÃæÕâ¶Î¼òµ¥µÄ´úÂë:
const App
=
(
<div>
<h1 id="title">Title</h1>
<a href="xxx">Jump</a>
<section>
<p>
Article
</p>
</section>
</div>
);
|
¾¹ýbabelת»»ºó¾Í±ä³ÉÁËÕâÑù£º

ÉÏÃæµÄ½ØÍ¼¿ÉÒÔ¿´³öÎÒÃÇдµÄHTML±»×ª»»³ÉÁËReact.createElement£¬ÎÒÃǽ«ÉÏÃæ´úÂëÉÔ΢¸ñʽ»¯À´¿´Ï£º
var App =
React.createElement(
'div',
null,
React.createElement(
'h1',
{
id: 'title',
},
'Title',
),
React.createElement(
'a',
{
href: 'xxx',
},
'Jump',
),
React.createElement(
'section',
null,
React.createElement('p', null, 'Article'),
),
);
|
´Óת»»ºóµÄ´úÂëÎÒÃÇ¿ÉÒÔ¿´³öReact.createElementÖ§³Ö¶à¸ö²ÎÊý:
1.type£¬Ò²¾ÍÊǽڵãÀàÐÍ
2.config, ÕâÊǽڵãÉϵÄÊôÐÔ£¬±ÈÈçidºÍhref
3.children, ´ÓµÚÈý¸ö²ÎÊý¿ªÊ¼¾ÍÈ«²¿ÊÇchildrenÒ²¾ÍÊÇ×ÓÔªËØÁË£¬×ÓÔªËØ¿ÉÒÔÓжà¸ö£¬ÀàÐÍ¿ÉÒÔÊǼòµ¥µÄÎı¾£¬Ò²¿ÉÒÔ»¹ÊÇReact.createElement£¬Èç¹ûÊÇReact.createElement£¬Æäʵ¾ÍÊÇ×Ó½ÚµãÁË£¬×Ó½ÚµãÏÂÃæ»¹¿ÉÒÔÓÐ×ӽڵ㡣ÕâÑù¾ÍÓÃReact.createElementµÄǶÌ×¹ØÏµÊµÏÖÁËHTML½ÚµãµÄÊ÷Ðνṹ¡£
ÈÃÎÒÃÇÀ´ÍêÕû¿´ÏÂÕâ¸ö¼òµ¥µÄReactÒ³Ãæ´úÂ룺

äÖȾÔÚÒ³ÃæÉÏÊÇÕâÑù£º

ÕâÀïÃæÓõ½ÁËReactµÄµØ·½Æäʵ¾ÍÁ½¸ö£¬Ò»¸öÊÇJSX£¬Ò²¾ÍÊÇReact.createElement£¬ÁíÒ»¸ö¾ÍÊÇReactDOM.render£¬ËùÒÔÎÒÃÇÊÖдµÄµÚÒ»¸öÄ¿±ê¾ÍÓÐÁË£¬¾ÍÊÇcreateElementºÍrenderÕâÁ½¸ö·½·¨¡£
ÊÖдcreateElement
¶ÔÓÚ<h1 id="title">Title</h1>ÕâÑùÒ»¸ö¼òµ¥µÄ½Úµã£¬ÔÉúDOMÒ²»á¸½¼ÓÒ»´ó¶ÑÊôÐԺͷ½·¨ÔÚÉÏÃæ£¬ËùÒÔÎÒÃÇÔÚcreateElementµÄʱºò×îºÃÄܽ«Ëüת»»ÎªÒ»ÖֱȽϼòµ¥µÄÊý¾Ý½á¹¹£¬Ö»°üº¬ÎÒÃÇÐèÒªµÄÔªËØ£¬±ÈÈçÕâÑù£º
{
type: 'h1',
props: {
id: 'title',
children: 'Title'
}
} |
ÓÐÁËÕâ¸öÊý¾Ý½á¹¹ºó£¬ÎÒÃǶÔÓÚDOMµÄ²Ù×÷Æäʵ¿ÉÒÔת»¯Îª¶ÔÕâ¸öÊý¾Ý½á¹¹µÄ²Ù×÷£¬ÐÂÀÏDOMµÄ¶Ô±ÈÆäʵҲ¿ÉÒÔת»¯ÎªÕâ¸öÊý¾Ý½á¹¹µÄ¶Ô±È£¬ÕâÑùÎÒÃǾͲ»ÐèҪÿ´Î²Ù×÷¶¼È¥äÖÈ¾Ò³Ãæ£¬¶øÊǵȵ½ÐèÒªäÖȾµÄʱºò²Å½«Õâ¸öÊý¾Ý½á¹¹äÖȾµ½Ò³ÃæÉÏ¡£ÕâÆäʵ¾ÍÊÇÐéÄâDOM£¡¶øÎÒÃÇcreateElement¾ÍÊǸºÔðÀ´¹¹½¨Õâ¸öÐéÄâDOMµÄ·½·¨£¬ÏÂÃæÎÒÃÇÀ´ÊµÏÖÏ£º
function createElement
(type, props, ...children) {
// ºËÐÄÂß¼²»¸´ÔÓ£¬ ½«²ÎÊý¶¼Èûµ½Ò»¸ö¶ÔÏóÉÏ·µ»Ø¾ÍÐÐ
// childrenÒ²Òª·Åµ½propsÀïÃæÈ¥£¬ ÕâÑùÎÒÃÇÔÚ×é¼þÀïÃæ¾ÍÄÜͨ¹ý this.props.childrenÄõ½×ÓÔªËØ
return {
type,
props: {
...props,
children
}
}
} |
ÊÖдrender
ÉÏÊö´úÂëÎÒÃÇÓÃcreateElement½«JSX´úÂëת»»³ÉÁËÐéÄâDOM£¬ÄÇÕæÕý½«ËüäÖȾµ½Ò³ÃæµÄº¯ÊýÊÇrender£¬ËùÒÔÎÒÃÇ»¹ÐèҪʵÏÖÏÂÕâ¸ö·½·¨£¬Í¨¹ýÎÒÃÇÒ»°ãµÄÓ÷¨ReactDOM.render(
<App />,document.getElementById('root'));¿ÉÒÔÖªµÀËû½ÓÊÕÁ½¸ö²ÎÊý£º
¡¤¸ù×é¼þ£¬ÆäʵÊÇÒ»¸öJSX×é¼þ£¬Ò²¾ÍÊÇÒ»¸öcreateElement·µ»ØµÄÐéÄâDOM
¡¤¸¸½Úµã£¬Ò²¾ÍÊÇÎÒÃÇÒª½«Õâ¸öÐéÄâDOMäÖȾµÄλÖÃ
ÓÐÁËÕâÁ½¸ö²ÎÊý£¬ÎÒÃÇÀ´ÊµÏÖÏÂrender·½·¨£º
function render
(vDom, container) {
let dom;
// ¼ì²éµ±Ç°½ÚµãÊÇÎı¾»¹ÊǶÔÏó
if (typeof vDom !== 'object') {
dom = document.createTextNode (vDom)
} else {
dom = document.createElement (vDom.type);
}
// ½«vDomÉϳýÁËchildrenÍâµÄÊôÐÔ¶¼ ¹ÒÔØµ½ÕæÕýµÄDOMÉÏÈ¥
if(vDom.props) {
Object.keys (vDom.props)
.filter (key => key != 'children')
.forEach (item => {
dom[item] = vDom.props[item];
})
}
// Èç¹û»¹ÓÐ×ÓÔªËØ£¬µÝ¹éµ÷ÓÃ
if (vDom.props && vDom.props.children && vDom.props.children.length) {
vDom.props.children.forEach (child => render(child, dom));
} container.appendChild (dom);
} |
ÏÖÔÚÎÒÃÇ¿ÉÒÔÓÃ×Ô¼ºÐ´µÄcreateElementºÍrenderÀ´Ìæ»»ÔÉúµÄ·½·¨ÁË£º

¿ÉÒԵõ½Ò»ÑùµÄäÖȾ½á¹û£º

ΪʲôÐèÒªFiber
ÉÏÃæÎÒÃǼòµ¥µÄʵÏÖÁËÐéÄâDOMäÖȾµ½Ò³ÃæÉϵĴúÂ룬Õⲿ·Ö¹¤×÷±»React¹Ù·½³ÆÎªrenderer£¬rendererÊǵÚÈý·½¿ÉÒÔ×Ô¼ºÊµÏÖµÄÒ»¸öÄ£¿é£¬»¹ÓиöºËÐÄÄ£¿é½Ð×öreconciler£¬reconcilerµÄÒ»´ó¹¦ÄܾÍÊÇ´ó¼ÒÊìÖªµÄdiff£¬Ëû»á¼ÆËã³öÓ¦¸Ã¸üÐÂÄÄÐ©Ò³Ãæ½Úµã£¬È»ºó½«ÐèÒª¸üеĽڵãÐéÄâDOM´«µÝ¸ørenderer£¬renderer¸ºÔð½«ÕâЩ½ÚµãäÖȾµ½Ò³ÃæÉÏ¡£µ«ÊÇÕâ¸öÁ÷³ÌÓиöÎÊÌ⣬ËäÈ»ReactµÄdiffËã·¨ÊǾ¹ýÓÅ»¯µÄ£¬µ«ÊÇËûÈ´ÊÇͬ²½µÄ£¬renderer¸ºÔð²Ù×÷DOMµÄappendChildµÈAPIÒ²ÊÇͬ²½µÄ£¬Ò²¾ÍÊÇ˵Èç¹ûÓдóÁ¿½ÚµãÐèÒª¸üУ¬JSÏ̵߳ÄÔËÐÐʱ¼ä¿ÉÄÜ»á±È½Ï³¤£¬ÔÚÕâ¶Îʱ¼ää¯ÀÀÆ÷ÊDz»»áÏìÓ¦ÆäËûʼþµÄ£¬ÒòΪJSÏ̺߳ÍGUIÏß³ÌÊÇ»¥³âµÄ£¬JSÔËÐÐÊ±Ò³Ãæ¾Í²»»áÏìÓ¦£¬Õâ¸öʱ¼äÌ«³¤ÁË£¬Óû§¾Í¿ÉÄÜ¿´µ½¿¨¶Ù£¬ÌرðÊǶ¯»µÄ¿¨¶Ù»áºÜÃ÷ÏÔ¡£ÔÚReactµÄ¹Ù·½Ñݽ²ÖÐÓиöÀý×Ó£¬¿ÉÒÔºÜÃ÷ÏԵĿ´µ½ÕâÖÖͬ²½¼ÆËãÔì³ÉµÄ¿¨¶Ù£º

¶øFiber¾ÍÊÇÓÃÀ´½â¾öÕâ¸öÎÊÌâµÄ£¬Fiber¿ÉÒÔ½«³¤Ê±¼äµÄͬ²½ÈÎÎñ²ð·Ö³É¶à¸öСÈÎÎñ£¬´Ó¶øÈÃä¯ÀÀÆ÷Äܹ»³éÉíÈ¥ÏìÓ¦ÆäËûʼþ£¬µÈËû¿ÕÁËÔÙ»ØÀ´¼ÌÐø¼ÆË㣬ÕâÑùÕû¸ö¼ÆËãÁ÷³Ì¾ÍÏÔµÃÆ½»¬ºÜ¶à¡£ÏÂÃæÊÇʹÓÃFiberºóµÄЧ¹û£º

ÔõôÀ´²ð·Ö
ÉÏÃæÎÒÃÇ×Ô¼ºÊµÏÖµÄrender·½·¨Ö±½ÓµÝ¹é±éÀúÁËÕû¸övDomÊ÷£¬Èç¹ûÎÒÃÇÔÚÖÐ;ijһ²½Í£ÏÂÀ´£¬Ï´ÎÔÙµ÷ÓÃʱÆäʵ²¢²»ÖªµÀÉÏ´ÎÔÚÄÄÀïÍ£ÏÂÀ´µÄ£¬²»ÖªµÀ´ÓÄÄÀ↑ʼ£¬ËùÒÔvDomµÄÊ÷Ðνṹ²¢²»Âú×ãÖÐ;ÔÝÍ££¬Ï´μÌÐøµÄÐèÇó£¬ÐèÒª¸ÄÔìÊý¾Ý½á¹¹¡£ÁíÒ»¸öÐèÒª½â¾öµÄÎÊÌâÊÇ£¬²ð·ÖÏÂÀ´µÄСÈÎÎñʲôʱºòÖ´ÐУ¿ÎÒÃǵÄÄ¿µÄÊÇÈÃÓû§ÓиüÁ÷³©µÄÌåÑ飬ËùÒÔÎÒÃÇ×îºÃ²»Òª×èÈû¸ßÓÅÏȼ¶µÄÈÎÎñ£¬±ÈÈçÓû§ÊäÈ룬¶¯»Ö®À࣬µÈËûÃÇÖ´ÐÐÍêÁËÎÒÃÇÔÙ¼ÆËã¡£ÄÇÎÒÔõô֪µÀÏÖÔÚÓÐûÓиßÓÅÏȼ¶ÈÎÎñ£¬ä¯ÀÀÆ÷ÊDz»ÊÇ¿ÕÏÐÄØ£¿×ܽáÏÂÀ´£¬FiberÒªÏë´ïµ½Ä¿µÄ£¬ÐèÒª½â¾öÁ½¸öÎÊÌ⣺
еÄÈÎÎñµ÷¶È£¬ÓиßÓÅÏȼ¶ÈÎÎñµÄʱºò½«ä¯ÀÀÆ÷ÈóöÀ´£¬µÈä¯ÀÀÆ÷¿ÕÁËÔÙ¼ÌÐøÖ´ÐÐ
еÄÊý¾Ý½á¹¹£¬¿ÉÒÔËæÊ±Öжϣ¬Ï´νøÀ´¿ÉÒÔ½Ó×ÅÖ´ÐÐ
requestIdleCallback
requestIdleCallbackÊÇÒ»¸öʵÑéÖеÄÐÂAPI£¬Õâ¸öAPIµ÷Ó÷½Ê½ÈçÏÂ:
// ¿ªÆôµ÷ÓÃ
var handle = window.requestIdleCallback (callback[, options]) // ½áÊøµ÷ÓÃ
Window.cancelIdleCallback (handle) |
requestIdleCallback½ÓÊÕÒ»¸ö»Øµ÷£¬Õâ¸ö»Øµ÷»áÔÚä¯ÀÀÆ÷¿ÕÏÐʱµ÷Óã¬Ã¿´Îµ÷ÓûᴫÈëÒ»¸öIdleDeadline£¬¿ÉÒÔÄõ½µ±Ç°»¹¿ÕÓà¶à¾Ã£¬options¿ÉÒÔ´«Èë²ÎÊý×î¶àµÈ¶à¾Ã£¬µÈµ½ÁËʱ¼ää¯ÀÀÆ÷»¹²»¿Õ¾ÍÇ¿ÖÆÖ´ÐÐÁË¡£Ê¹ÓÃÕâ¸öAPI¿ÉÒÔ½â¾öÈÎÎñµ÷¶ÈµÄÎÊÌ⣬ÈÃä¯ÀÀÆ÷ÔÚ¿ÕÏÐʱ²Å¼ÆËãdiff²¢äÖȾ¡£¸ü¶à¹ØÓÚrequestIdleCallbackµÄʹÓÿÉÒԲ鿴MDNµÄÎĵµ¡£µ«ÊÇÕâ¸öAPI»¹ÔÚʵÑéÖУ¬¼æÈÝÐÔ²»ºÃ£¬ËùÒÔReact¹Ù·½×Ô¼ºÊµÏÖÁËÒ»Ìס£±¾ÎÄ»á¼ÌÐøÊ¹ÓÃrequestIdleCallbackÀ´½øÐÐÈÎÎñµ÷¶È£¬ÎÒÃǽøÐÐÈÎÎñµ÷¶ÈµÄ˼ÏëÊǽ«ÈÎÎñ²ð·Ö³É¶à¸öСÈÎÎñ£¬requestIdleCallbackÀïÃæ²»¶ÏµÄ°ÑСÈÎÎñÄóöÀ´Ö´ÐУ¬µ±ËùÓÐÈÎÎñ¶¼Ö´ÐÐÍê»òÕß³¬Ê±Á˾ͽáÊø±¾´ÎÖ´ÐУ¬Í¬Ê±Òª×¢²áÏ´ÎÖ´ÐУ¬´úÂë¼Ü×Ó¾ÍÊÇÕâÑù£º
function workLoop
(deadline) {
while (nextUnitOfWork && deadline.timeRemaining() > 1) {
// Õâ¸öwhileÑ»·»áÔÚÈÎÎñ Ö´ÐÐÍê»òÕßʱ¼äµ½Á˵Äʱºò½áÊø
nextUnitOfWork = performUnitOfWork (nextUnitOfWork);
} // Èç¹ûÈÎÎñ»¹Ã»Í꣬µ«ÊÇʱ¼äµ½ÁË£¬ ÎÒÃÇÐèÒª¼ÌÐø×¢²á requestIdleCallback
requestIdleCallback (workLoop);
} // performUnitOfWorkÓÃÀ´Ö´ÐÐÈÎÎñ£¬ ²ÎÊýÊÇÎÒÃǵĵ±Ç°fiberÈÎÎñ£¬·µ»ØÖµÊÇÏÂÒ»¸öÈÎÎñ
function performUnitOfWork(fiber) {
}
requestIdleCallback (workLoop); |
ÉÏÊöworkLoop¶ÔÓ¦ReactÔ´Âë¿´ÕâÀï¡£
Fiber¿ÉÖжÏÊý¾Ý½á¹¹
ÉÏÃæÎÒÃǵÄperformUnitOfWork²¢Ã»ÓÐʵÏÖ£¬µ«ÊÇ´ÓÉÏÃæµÄ½á¹¹¿ÉÒÔ¿´³öÀ´£¬Ëû½ÓÊյIJÎÊýÊÇÒ»¸öСÈÎÎñ£¬Í¬Ê±Í¨¹ýÕâ¸öСÈÎÎñ»¹¿ÉÒÔÕÒµ½ËûµÄÏÂÒ»¸öСÈÎÎñ£¬Fiber¹¹½¨µÄ¾ÍÊÇÕâÑùÒ»¸öÊý¾Ý½á¹¹¡£Fiber֮ǰµÄÊý¾Ý½á¹¹ÊÇÒ»¿ÃÊ÷£¬¸¸½ÚµãµÄchildrenÖ¸ÏòÁË×ӽڵ㣬µ«ÊÇÖ»ÓÐÕâÒ»¸öÖ¸ÕëÊDz»ÄÜʵÏÖÖжϼÌÐøµÄ¡£±ÈÈçÎÒÏÖÔÚÓÐÒ»¸ö¸¸½ÚµãA£¬AÓÐÈý¸ö×Ó½ÚµãB,C,D£¬µ±ÎÒ±éÀúµ½CµÄʱºòÖжÏÁË£¬ÖØÐ¿ªÊ¼µÄʱºò£¬ÆäʵÎÒÊDz»ÖªµÀCÏÂÃæ¸ÃÖ´ÐÐÄĸöµÄ£¬ÒòΪֻ֪µÀC£¬²¢Ã»ÓÐÖ¸ÕëÖ¸ÏòËûµÄ¸¸½Úµã£¬Ò²Ã»ÓÐÖ¸ÕëÖ¸ÏòËûµÄÐֵܡ£Fiber¾ÍÊǸÄÔìÁËÕâÑùÒ»¸ö½á¹¹£¬¼ÓÉÏÁËÖ¸Ïò¸¸½ÚµãºÍÐֵܽڵãµÄÖ¸Õ룺

ÉÏÃæµÄͼƬ»¹ÊÇÀ´×ÔÓÚ¹Ù·½µÄÑݽ²£¬¿ÉÒÔ¿´µ½ºÍ֮ǰ¸¸½ÚµãÖ¸ÏòËùÓÐ×ӽڵ㲻ͬ£¬ÕâÀïÓÐÈý¸öÖ¸Õ룺
1.child: ¸¸½ÚµãÖ¸ÏòµÚÒ»¸ö×ÓÔªËØµÄÖ¸Õë¡£
2.sibling£º´ÓµÚÒ»¸ö×ÓÔªËØÍùºó£¬Ö¸ÏòÏÂÒ»¸öÐÖµÜÔªËØ¡£
3.return£ºËùÓÐ×ÓÔªËØ¶¼ÓеÄÖ¸Ïò¸¸ÔªËصÄÖ¸Õë¡£
ÓÐÁËÕ⼸¸öÖ¸Õëºó£¬ÎÒÃÇ¿ÉÒÔÔÚÈÎÒâÒ»¸öÔªËØÖжϱéÀú²¢»Ö¸´£¬±ÈÈçÔÚÉÏͼList´¦ÖжÏÁË£¬»Ö¸´µÄʱºò¿ÉÒÔͨ¹ýchildÕÒµ½ËûµÄ×ÓÔªËØ£¬Ò²¿ÉÒÔͨ¹ýreturnÕÒµ½ËûµÄ¸¸ÔªËØ£¬Èç¹ûËû»¹ÓÐÐֵܽڵãÒ²¿ÉÒÔÓÃsiblingÕÒµ½¡£FiberÕâ¸ö½á¹¹ÍâÐο´×Å»¹ÊÇ¿ÃÊ÷£¬µ«ÊÇûÓÐÁËÖ¸ÏòËùÓÐ×ÓÔªËØµÄÖ¸Õ룬¸¸½ÚµãÖ»Ö¸ÏòµÚÒ»¸ö×ӽڵ㣬Ȼºó×Ó½ÚµãÓÐÖ¸ÏòÆäËû×Ó½ÚµãµÄÖ¸Õ룬ÕâÆäʵÊǸöÁ´±í¡£
ʵÏÖFiber
ÏÖÔÚÎÒÃÇ¿ÉÒÔ×Ô¼ºÀ´ÊµÏÖÒ»ÏÂFiberÁË£¬ÎÒÃÇÐèÒª½«Ö®Ç°µÄvDom½á¹¹×ª»»ÎªFiberµÄÊý¾Ý½á¹¹£¬Í¬Ê±ÐèÒªÄܹ»Í¨¹ýÆäÖÐÈÎÒâÒ»¸ö½Úµã·µ»ØÏÂÒ»¸ö½Úµã£¬Æäʵ¾ÍÊDZéÀúÕâ¸öÁ´±í¡£±éÀúµÄʱºò´Ó¸ù½Úµã³ö·¢£¬ÏÈÕÒ×ÓÔªËØ£¬Èç¹û×ÓÔªËØ´æÔÚ£¬Ö±½Ó·µ»Ø£¬Èç¹ûûÓÐ×ÓÔªËØÁ˾ÍÕÒÐÖµÜÔªËØ£¬ÕÒÍêËùÓеÄÐÖµÜÔªËØºóÔÙ·µ»Ø¸¸ÔªËØ£¬È»ºóÔÙÕÒÕâ¸ö¸¸ÔªËصÄÐÖµÜÔªËØ¡£Õû¸ö±éÀú¹ý³ÌÆäʵÊǸöÉî¶ÈÓÅÏȱéÀú£¬´ÓÉϵ½Ï£¬È»ºó×îºóÒ»ÐпªÊ¼´Ó×óµ½ÓÒ±éÀú¡£±ÈÈçÏÂͼ´Ódiv1¿ªÊ¼±éÀúµÄ»°£¬±éÀúµÄ˳Ðò¾ÍÓ¦¸ÃÊÇdiv1
-> div2 -> h1 -> a -> div2 -> p ->
div1¡£¿ÉÒÔ¿´µ½Õâ¸öÐòÁÐÖУ¬µ±ÎÒÃÇreturn¸¸½Úµãʱ£¬ÕâЩ¸¸½Úµã»á±»µÚ¶þ´Î±éÀú£¬ËùÒÔÎÒÃÇд´úÂëʱ£¬returnµÄ¸¸½Úµã²»»á×÷ΪÏÂÒ»¸öÈÎÎñ·µ»Ø£¬Ö»ÓÐsiblingºÍchild²Å»á×÷ΪÏÂÒ»¸öÈÎÎñ·µ»Ø¡£

// performUnitOfWorkÓÃÀ´Ö´ÐÐÈÎÎñ£¬ ²ÎÊýÊÇÎÒÃǵĵ±Ç°fiberÈÎÎñ£¬·µ»ØÖµÊÇÏÂÒ»¸öÈÎÎñ
function performUnitOfWork (fiber) {
// ¸ù½ÚµãµÄdom¾ÍÊÇcontainer£¬Èç¹ûûÓÐÕâ¸öÊôÐÔ £¬ËµÃ÷µ±Ç°fiber²»ÊǸù½Úµã
if (!fiber.dom) {
fiber.dom = createDom (fiber); // ´´½¨Ò»¸öDOM¹ÒÔØÉÏÈ¥
} // Èç¹ûÓи¸½Úµã£¬½«µ±Ç°½Úµã¹ÒÔØµ½¸¸½ÚµãÉÏ
if (fiber.return) {
fiber.return.dom.appendChild (fiber.dom);
} // ½«ÎÒÃÇÇ°ÃæµÄvDom½á¹¹×ª»»Îªfiber½á¹¹
const elements = fiber.children;
let prevSibling = null;
if (elements && elements.length) {
for (let i = 0; i < elements.length; i++)
{
const element = elements[i];
const newFiber = {
type: element.type,
props: element.props,
return: fiber,
dom: null
} // ¸¸¼¶µÄchildÖ¸ÏòµÚÒ»¸ö×ÓÔªËØ
if(i === 0) {
fiber.child = newFiber;
} else {
// ÿ¸ö×ÓÔªËØÓµÓÐÖ¸ÏòÏÂÒ»¸ö×ÓÔªËØµÄÖ¸Õë
prevSibling.sibling = newFiber;
} prevSibling = newFiber;
}
} // Õâ¸öº¯ÊýµÄ·µ»ØÖµÊÇÏÂÒ»¸öÈÎÎñ£¬ ÕâÆäʵÊÇÒ»¸öÉî¶ÈÓÅÏȱéÀú
// ÏÈÕÒ×ÓÔªËØ£¬Ã»ÓÐ×ÓÔªËØÁ˾ÍÕÒÐÖµÜÔªËØ
// ÐÖµÜÔªËØÒ²Ã»ÓÐÁ˾ͷµ»Ø¸¸ÔªËØ
// È»ºóÔÙÕÒÕâ¸ö¸¸ÔªËصÄÐÖµÜÔªËØ
// ×îºóµ½¸ù½Úµã½áÊø
// Õâ¸ö±éÀúµÄ˳ÐòÆäʵ¾ÍÊÇ´ÓÉϵ½Ï£¬´Ó×óµ½ÓÒ
if (fiber.child) {
return fiber.child;
} let nextFiber = fiber;
while (nextFiber) {
if (nextFiber.sibling) {
return nextFiber.sibling;
} nextFiber = nextFiber.return;
}
} |
ReactÔ´ÂëÖеÄperformUnitOfWork¿´ÕâÀµ±È»±ÈÎÒÃÇÕâ¸ö¸´ÔӺܶࡣ
ͳһcommit DOM²Ù×÷
ÉÏÃæÎÒÃǵÄperformUnitOfWorkÒ»±ß¹¹½¨Fiber½á¹¹Ò»±ß²Ù×÷DOMappendChild£¬ÕâÑùÈç¹ûij´Î¸üкü¸¸ö½Úµã£¬²Ù×÷Á˵ÚÒ»¸ö½ÚµãÖ®ºó¾ÍÖжÏÁË£¬ÄÇÎÒÃÇ¿ÉÄÜÖ»¿´µ½µÚÒ»¸ö½ÚµãäÖȾµ½ÁËÒ³Ãæ£¬ºóÐø¼¸¸ö½ÚµãµÈä¯ÀÀÆ÷¿ÕÁ˲ÅÂ½ÐøäÖȾ¡£ÎªÁ˱ÜÃâÕâÖÖÇé¿ö£¬ÎÒÃÇÓ¦¸Ã½«DOM²Ù×÷¶¼ËѼ¯ÆðÀ´£¬×îºóͳһִÐУ¬Õâ¾ÍÊÇcommit¡£ÎªÁËÄܹ»¼Ç¼λÖã¬ÎÒÃÇ»¹ÐèÒªÒ»¸öÈ«¾Ö±äÁ¿workInProgressRootÀ´¼Ç¼¸ù½Úµã£¬È»ºóÔÚworkLoop¼ì²âÈç¹ûÈÎÎñÖ´ÐÐÍêÁË£¬¾Ícommit:
function workLoop
(deadline) {
while (nextUnitOfWork && deadline.timeRemaining()
> 1) {
// Õâ¸öwhileÑ»·»áÔÚÈÎÎñÖ´ÐÐÍê»òÕßʱ¼äµ½Á˵Äʱºò½áÊø
nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
} // ÈÎÎñ×öÍêºóͳһäÖȾ
if (!nextUnitOfWork && workInProgressRoot)
{
commitRoot();
} // Èç¹ûÈÎÎñ»¹Ã»Í꣬µ«ÊÇʱ¼äµ½ÁË£¬ ÎÒÃÇÐèÒª¼ÌÐø×¢²árequestIdleCallback
requestIdleCallback (workLoop);
} |
ÒòΪÎÒÃÇÊÇÔÚFiberÊ÷ÍêÈ«¹¹½¨ºóÔÙÖ´ÐеÄcommit£¬¶øÇÒÓÐÒ»¸ö±äÁ¿workInProgressRootÖ¸ÏòÁËFiberµÄ¸ù½Úµã£¬ËùÒÔÎÒÃÇ¿ÉÒÔÖ±½Ó°ÑworkInProgressRootÄùýÀ´µÝ¹éäÖȾ¾ÍÐÐÁË£º
// ͳһ²Ù×÷DOM
function commitRoot() {
commitRootImpl (workInProgressRoot.child); // ¿ªÆôµÝ¹é
workInProgressRoot = null; / ²Ù×÷Íêºó½«workInProgressRootÖØÖÃ
} function commitRootImpl (fiber) {
if(!fiber) {
return;
} const parentDom = fiber.return.dom;
parentDom.appendChild (fiber.dom); // µÝ¹é²Ù×÷×ÓÔªËØºÍÐÖµÜÔªËØ
commitRootImpl (fiber.child);
commitRootImpl (fiber.sibling);
} |
reconcileµ÷ºÍ
reconcileÆäʵ¾ÍÊÇÐéÄâDOMÊ÷µÄdiff²Ù×÷£¬ÐèҪɾ³ý²»ÐèÒªµÄ½Úµã£¬¸üÐÂÐ޸ĹýµÄ½Úµã£¬Ìí¼ÓеĽڵ㡣ΪÁËÔÚÖжϺóÄܻص½¹¤×÷λÖã¬ÎÒÃÇ»¹ÐèÒªÒ»¸ö±äÁ¿currentRoot£¬È»ºóÔÚfiber½ÚµãÀïÃæÌí¼ÓÒ»¸öÊôÐÔalternate£¬Õâ¸öÊôÐÔÖ¸ÏòÉÏÒ»´ÎÔËÐеĸù½Úµã£¬Ò²¾ÍÊÇcurrentRoot¡£currentRoot»áÔÚµÚÒ»´ÎrenderºóµÄcommit½×¶Î¸³Öµ£¬Ò²¾ÍÊÇÿ´Î¼ÆËãÍêºó¶¼»á°Ñµ±´Î״̬¼Ç¼ÔÚalternateÉÏ£¬ºóÃæ¸üÐÂÁ˾ͿÉÒÔ°ÑalternateÄóöÀ´¸úеÄ״̬×ödiff¡£È»ºóperformUnitOfWorkÀïÃæÐèÒªÌí¼Óµ÷ºÍ×ÓÔªËØµÄ´úÂ룬¿ÉÒÔÐÂÔöÒ»¸öº¯ÊýreconcileChildren¡£Õâ¸öº¯ÊýÀïÃæ²»Äܼòµ¥µÄ´´½¨Ð½ڵãÁË£¬¶øÊÇÒª½«ÀϽڵã¸úнڵãÄÃÀ´¶Ô±È£¬¶Ô±ÈÂß¼ÈçÏÂ:
1.Èç¹ûÐÂÀϽڵãÀàÐÍÒ»Ñù£¬¸´ÓÃÀϽڵãDOM£¬¸üÐÂprops
2.Èç¹ûÀàÐͲ»Ò»Ñù£¬¶øÇÒÐÂµÄ½Úµã´æÔÚ£¬´´½¨Ð½ڵãÌæ»»ÀϽڵã
3.Èç¹ûÀàÐͲ»Ò»Ñù£¬Ã»ÓÐнڵ㣬ÓÐÀϽڵ㣬ɾ³ýÀϽڵã
×¢Òâɾ³ýÀϽڵãµÄ²Ù×÷ÊÇÖ±½Ó½«oldFiber¼ÓÉÏÒ»¸öɾ³ý±ê¼Ç¾ÍÐУ¬Í¬Ê±ÓÃÒ»¸öÈ«¾Ö±äÁ¿deletions¼Ç¼ËùÓÐÐèҪɾ³ýµÄ½Úµã£º
// ¶Ô±ÈoldFiberºÍµ±Ç°element
const sameType = oldFiber && element && oldFiber.type === element.type; //¼ì²âÀàÐÍÊDz»ÊÇÒ»Ñù
// ÏȱȽÏÔªËØÀàÐÍ
if (sameType) {
// Èç¹ûÀàÐÍÒ»Ñù£¬¸´Óýڵ㣬¸üÐÂprops
newFiber = {
type: oldFiber.type,
props: element.props,
dom: oldFiber.dom,
return: workInProgressFiber,
alternate: oldFiber, // ¼Ç¼ÏÂÉÏ´Î״̬
effectTag: 'UPDATE' // Ìí¼ÓÒ»¸ö²Ù×÷±ê¼Ç
}
} else if(!sameType && element) {
// Èç¹ûÀàÐͲ»Ò»Ñù£¬ ÓÐеĽڵ㣬´´½¨Ð½ڵãÌæ»»ÀϽڵã
newFiber = {
type: element.type,
props: element.props,
dom: null, // ¹¹½¨fiberʱûÓÐdom£¬ Ï´ÎperformÕâ¸ö½ÚµãÊDzŴ´½¨dom
return: workInProgressFiber,
alternate: null, // ÐÂÔöµÄûÓÐÀÏ״̬
effectTag: 'REPLACEMENT' // Ìí¼ÓÒ»¸ö²Ù×÷±ê¼Ç
}
} else if(!sameType && oldFiber) {
// Èç¹ûÀàÐͲ»Ò»Ñù£¬Ã»ÓÐнڵ㣬ÓÐÀϽڵ㣬ɾ³ýÀϽڵã
oldFiber.effectTag = 'DELETION'; // Ìí¼Óɾ³ý±ê¼Ç
deletions.push(oldFiber); // Ò»¸öÊý×éÊÕ¼¯ËùÓÐÐèҪɾ³ýµÄ½Úµã
}
|
È»ºó¾ÍÊÇÔÚcommit½×¶Î´¦ÀíÕæÕýµÄDOM²Ù×÷£¬¾ßÌåµÄ²Ù×÷ÊǸù¾ÝÎÒÃǵÄeffectTagÀ´ÅжϵÄ:
function commitRootImpl(fiber)
{
if(!fiber) {
return;
}
const parentDom = fiber.return.dom;
if (fiber.effectTag === 'REPLACEMENT' &&
fiber.dom) {
parentDom.appendChild(fiber.dom);
} else if (fiber.effectTag === 'DELETION') {
parentDom.removeChild(fiber.dom);
} else if (fiber.effectTag === 'UPDATE' && fiber.dom)
{
// ¸üÐÂDOMÊôÐÔ
updateDom (fiber.dom, fiber.alternate.props, fiber.props);
} // µÝ¹é²Ù×÷×ÓÔªËØºÍÐÖµÜÔªËØ
commitRootImpl(fiber.child);
commitRootImpl(fiber.sibling);
} |
Ìæ»»ºÍɾ³ýµÄDOM²Ù×÷¶¼±È½Ï¼òµ¥£¬¸üÐÂÊôÐԵĻáÉÔ΢Âé·³µã£¬ÐèÒªÔÙдһ¸ö¸¨Öúº¯ÊýupdateDomÀ´ÊµÏÖ:
// ¸üÐÂDOMµÄ²Ù×÷
function updateDom (dom, prevProps, nextProps) {
// 1. ¹ýÂËchildrenÊôÐÔ
// 2. ÀϵĴæÔÚ£¬ÐµÄûÁË£¬È¡Ïû
// 3. еĴæÔÚ£¬ÀϵÄûÓУ¬ÐÂÔö
Object.keys(prevProps)
.filter (name => name !== 'children')
.filter (name => !(name in nextProps))
.forEach(name => {
if(name.indexOf('on') === 0) {
dom.removeEventListener (name.substr(2).toLowerCase(), prevProps[name], false);
} else {
dom[name] = '';
}
}); Object.keys (nextProps)
.filter (name => name !== 'children')
.forEach(name => {
if (name.indexOf('on') === 0) {
dom.addEventListener (name.substr(2).toLowerCase(), nextProps[name],
false);
} else {
dom[name] = nextProps[name];
}
});
} |
updateDomµÄ´úÂëдµÄ±È½Ï¼òµ¥£¬Ê¼þÖ»´¦ÀíÁ˼òµ¥µÄon¿ªÍ·µÄ£¬¼æÈÝÐÔÒ²ÓÐÎÊÌ⣬prevPropsºÍnextProps¿ÉÄÜ»á±éÀúµ½ÏàͬµÄÊôÐÔ£¬ÓÐÖØ¸´¸³Öµ£¬µ«ÊÇ×ÜÌåÔÀí»¹ÊÇû´íµÄ¡£ÒªÏë°ÑÕâ¸ö´¦Àíдȫ£¬´úÂëÁ¿»¹ÊDz»Éٵġ£
º¯Êý×é¼þ
º¯Êý×é¼þÊÇReactÀïÃæºÜ³£¼ûµÄÒ»ÖÖ×é¼þ£¬ÎÒÃÇÇ°ÃæµÄReact¼Ü¹¹ÆäʵÒѾдºÃÁË£¬ÎÒÃÇÕâÀïÀ´Ö§³ÖϺ¯Êý×é¼þ¡£ÎÒÃÇ֮ǰµÄfiber½ÚµãÉϵÄtype¶¼ÊÇDOM½ÚµãµÄÀàÐÍ£¬±ÈÈçh1ʲôµÄ£¬µ«ÊǺ¯Êý×é¼þµÄ½ÚµãtypeÆäʵ¾ÍÊÇÒ»¸öº¯ÊýÁË£¬ÎÒÃÇÐèÒª¶ÔÕâÖÖ½Úµã½øÐе¥¶À´¦Àí¡£
Ê×ÏÈÐèÒªÔÚ¸üеÄʱºò¼ì²âµ±Ç°½ÚµãÊDz»ÊǺ¯Êý×é¼þ£¬Èç¹ûÊÇ£¬childrenµÄ´¦ÀíÂß¼»áÉÔ΢²»Ò»Ñù:
// performUnitOfWork˕̾
// ¼ì²âº¯Êý×é¼þ
function performUnitOfWork(fiber) {
const isFunctionComponent = fiber.type instanceof Function;
if (isFunctionComponent) {
updateFunctionComponent (fiber);
} else {
updateHostComponent(fiber);
}
// ...ÏÂÃæÊ¡ÂÔnÐдúÂë...
} function updateFunctionComponent (fiber) {
// º¯Êý×é¼þµÄtype¾ÍÊǸöº¯Êý£¬ Ö±½ÓÄÃÀ´Ö´ÐпÉÒÔ»ñµÃDOMÔªËØ
const children = [fiber.type(fiber.props)]; reconcileChildren (fiber, children);
} // updateHostComponent¾ÍÊÇ֮ǰµÄ²Ù×÷£¬ Ö»Êǵ¥¶À³éÈ¡ÁËÒ»¸ö·½·¨
function updateHostComponent(fiber) {
if(!fiber.dom) {
fiber.dom = createDom(fiber); // ´´½¨Ò»¸öDOM¹ÒÔØÉÏÈ¥
} // ½«ÎÒÃÇÇ°ÃæµÄvDom½á¹¹×ª»»Îªfiber½á¹¹
const elements = fiber.props.children; // µ÷ºÍ×ÓÔªËØ
reconcileChildren (fiber, elements);
} |
È»ºóÔÚÎÒÃÇÌá½»DOM²Ù×÷µÄʱºòÒòΪº¯Êý×é¼þûÓÐDOMÔªËØ£¬ËùÒÔÐèҪעÒâÁ½µã£º
»ñÈ¡¸¸¼¶DOMÔªËØµÄʱºòÐèÒªµÝ¹éÍøÉÏÕÒÕæÕýµÄDOM
ɾ³ý½ÚµãµÄʱºòÐèÒªµÝ¹éÍùÏÂÕÒÕæÕýµÄ½Úµã
ÎÒÃÇÀ´ÐÞ¸ÄÏÂcommitRootImpl:
function commitRootImpl()
{
// const parentDom = fiber.return.dom;
// ÏòÉϲéÕÒÕæÕýµÄDOM
let parentFiber = fiber.return;
while(!parentFiber.dom) {
parentFiber = parentFiber.return;
}
const parentDom = parentFiber.dom;
// ...ÕâÀïÊ¡ÂÔnÐдúÂë...
if{fiber.effectTag === 'DELETION'} {
commitDeletion(fiber, parentDom);
}
}
function commitDeletion (fiber, domParent)
{
if(fiber.dom) {
// dom´æÔÚ£¬ÊÇÆÕͨ½Úµã
domParent.removeChild (fiber.dom);
} else {
// dom²»´æÔÚ£¬ÊǺ¯Êý×é¼þ,Ïòϵݹé²éÕÒÕæÊµDOM
commitDeletion (fiber.child, domParent);
}
} |
ÏÖÔÚÎÒÃÇ¿ÉÒÔ´«È뺯Êý×é¼þÁË:
import React
from './myReact';
const ReactDOM = React;
function App(props) {
return (
<div>
<h1 id="title">{props.title}</h1>
<a href="xxx">Jump</a>
<section>
<p>
Article
</p>
</section>
</div>
);
} ReactDOM.render(
<App title="Fiber Demo"/>,
document.getElementById('root')
); |
ʵÏÖuseState
useStateÊÇReact HooksÀïÃæµÄÒ»¸öAPI£¬Ï൱ÓÚ֮ǰClass
ComponentÀïÃæµÄstate£¬ÓÃÀ´¹ÜÀí×é¼þÄÚ²¿×´Ì¬£¬ÏÖÔÚÎÒÃÇÒѾÓÐÒ»¸ö¼ò»¯°æµÄReactÁË£¬ÎÒÃÇÒ²¿ÉÒÔ³¢ÊÔÏÂÀ´ÊµÏÖÕâ¸öAPI¡£
¼òµ¥°æ
ÎÒÃÇ»¹ÊÇ´ÓÓ÷¨ÈëÊÖÀ´ÊµÏÖ×î¼òµ¥µÄ¹¦ÄÜ£¬ÎÒÃÇÒ»°ãʹÓÃuseStateÊÇÕâÑùµÄ£º
function App(props)
{
const [count, setCount] = React.useState(1);
const onClickHandler = () => {
setCount(count + 1);
}
return (
<div>
<h1>Count: {count}</h1>
<button onClick= {onClickHandler}>Count+1</button>
</div>
);
} ReactDOM.render(
<App title="Fiber Demo"/>,
document.getElementById('root')
); |
ÉÏÊö´úÂë¿ÉÒÔ¿´³ö£¬ÎÒÃǵÄuseState½ÓÊÕÒ»¸ö³õʼֵ£¬·µ»ØÒ»¸öÊý×飬ÀïÃæÓÐÕâ¸östateµÄµ±Ç°ÖµºÍ¸Ä±ästateµÄ·½·¨£¬ÐèҪעÒâµÄÊÇApp×÷Ϊһ¸öº¯Êý×é¼þ£¬Ã¿´ÎrenderµÄʱºò¶¼»áÔËÐУ¬Ò²¾ÍÊÇ˵ÀïÃæµÄ¾Ö²¿±äÁ¿Ã¿´ÎrenderµÄʱºò¶¼»áÖØÖã¬ÄÇÎÒÃǵÄstate¾Í²»ÄÜ×÷Ϊһ¸ö¾Ö²¿±äÁ¿£¬¶øÊÇÓ¦¸Ã×÷Ϊһ¸öÈ«²¿±äÁ¿´æ´¢£º
let state = null;
function useState(init) {
state = state === null ? init : state; // ÐÞ¸ÄstateµÄ·½·¨
const setState = value => {
state = value; // Ö»ÒªÐÞ¸ÄÁËstate£¬ÎÒÃǾÍÐèÒªÖØÐ´¦Àí½Úµã
workInProgressRoot = {
dom: currentRoot.dom,
props: currentRoot.props,
alternate: currentRoot
} // ÐÞ¸ÄnextUnitOfWorkÖ¸ÏòworkInProgressRoot £¬ÕâÑùÏ´ξͻᴦÀíÕâ¸ö½ÚµãÁË
nextUnitOfWork = workInProgressRoot;
deletions = [];
} return [state, setState]
} |
ÕâÑùÆäʵÎÒÃǾͿÉÒÔʹÓÃÁË£º

Ö§³Ö¶à¸östate
ÉÏÃæµÄ´úÂëÖ»ÓÐÒ»¸östate±äÁ¿£¬Èç¹ûÎÒÃÇÓжà¸öuseStateÔõô°ìÄØ£¿ÎªÁËÄÜÖ§³Ö¶à¸öuseState£¬ÎÒÃǵÄstate¾Í²»ÄÜÊÇÒ»¸ö¼òµ¥µÄÖµÁË£¬ÎÒÃÇ¿ÉÒÔ¿¼ÂǰÑËû¸Ä³ÉÒ»¸öÊý×飬¶à¸öuseState°´ÕÕµ÷ÓÃ˳Ðò·Å½øÕâ¸öÊý×éÀïÃæ£¬·ÃÎʵÄʱºòͨ¹ýϱêÀ´·ÃÎÊ:
let state
= [];
let hookIndex = 0;
function useState(init) {
const currentIndex = hookIndex;
state[currentIndex] = state [currentIndex] === undefined ? init : state[currentIndex]; // ÐÞ¸ÄstateµÄ·½·¨
const setState = value => {
state[currentIndex] = value; // Ö»ÒªÐÞ¸ÄÁËstate£¬ÎÒÃǾÍÐèÒªÖØÐ´¦ÀíÕâ¸ö½Úµã
workInProgressRoot = {
dom: currentRoot.dom,
props: currentRoot.props,
alternate: currentRoot
} // ÐÞ¸ÄnextUnitOfWorkÖ¸ÏòworkInProgressRoot£¬ ÕâÑùÏ´ξͻᴦÀíÕâ¸ö½ÚµãÁË
nextUnitOfWork = workInProgressRoot;
deletions = [];
} hookIndex++; return [state[currentIndex], setState]
} |
À´¿´¿´¶à¸öuseStateµÄЧ¹û£º

Ö§³Ö¶à¸ö×é¼þ
ÉÏÃæµÄ´úÂëËäÈ»ÎÒÃÇÖ§³ÖÁ˶à¸öuseState£¬µ«ÊÇÈÔȻֻÓÐÒ»Ì×È«¾Ö±äÁ¿£¬Èç¹ûÓжà¸öº¯Êý×é¼þ£¬Ã¿¸ö×é¼þ¶¼À´²Ù×÷Õâ¸öÈ«¾Ö±äÁ¿£¬ÄÇÏ໥֮¼ä²»¾ÍÊÇÎÛȾÁËÊý¾ÝÁËÂð£¿ËùÒÔÎÒÃÇÊý¾Ý»¹²»Äܶ¼´æÔÚÈ«¾Ö±äÁ¿ÉÏÃæ£¬¶øÊÇÓ¦¸Ã´æÔÚÿ¸öfiber½ÚµãÉÏ£¬´¦ÀíÕâ¸ö½ÚµãµÄʱºòÔÙ½«×´Ì¬·Åµ½È«¾Ö±äÁ¿ÓÃÀ´Í¨Ñ¶:
// ÉêÃ÷Á½¸öÈ«¾Ö±äÁ¿£¬ÓÃÀ´´¦ÀíuseState
// wipFiberÊǵ±Ç°µÄº¯Êý×é¼þfiber½Úµã
// hookIndexÊǵ±Ç°º¯Êý×é¼þÄÚ²¿useState״̬¼ÆÊý
let wipFiber = null;
let hookIndex = null; |
ÒòΪuseStateÖ»ÔÚº¯Êý×é¼þÀïÃæ¿ÉÒÔÓã¬ËùÒÔÎÒÃÇ֮ǰµÄupdateFunctionComponentÀïÃæÐèÒª³õʼ»¯´¦ÀíuseState±äÁ¿:
function updateFunctionComponent
(fiber) {
// Ö§³ÖuseState£¬³õʼ»¯±äÁ¿
wipFiber = fiber;
hookIndex = 0;
wipFiber.hooks = []; // hooksÓÃÀ´´æ´¢¾ßÌåµÄstateÐòÁÐ
// ......ÏÂÃæ´úÂëÊ¡ÂÔ......
} |
ÒòΪhooks¶ÓÁзŵ½fiber½ÚµãÉÏÈ¥ÁË£¬ËùÒÔÎÒÃÇÔÚuseStateȡ֮ǰµÄֵʱÐèÒª´Ófiber.alternateÉÏÈ¡£¬ÍêÕû´úÂëÈçÏ£º
function useState(init)
{
// È¡³öÉϴεÄHook
const oldHook = wipFiber.alternate &&
wipFiber.alternate.hooks && wipFiber.alternate.hooks [hookIndex]; // hookÊý¾Ý½á¹¹
const hook = {
state: oldHook ? oldHook.state : init // stateÊÇÿ¸ö¾ßÌåµÄÖµ
} // ½«ËùÓÐuseStateµ÷Óð´ÕÕ˳Ðò´æµ½fiber½ÚµãÉÏ
wipFiber.hooks.push(hook);
hookIndex++; // ÐÞ¸ÄstateµÄ·½·¨
const setState = value => {
hook.state = value; // Ö»ÒªÐÞ¸ÄÁËstate£¬ÎÒÃǾÍÐèÒªÖØÐ´¦ÀíÕâ¸ö½Úµã
workInProgressRoot = {
dom: currentRoot.dom,
props: currentRoot.props,
alternate: currentRoot
} // ÐÞ¸ÄnextUnitOfWorkÖ¸ÏòworkInProgressRoot£¬ ÕâÑùÏ´ÎrequestIdleCallback¾Í»á´¦ÀíÕâ¸ö½ÚµãÁË
nextUnitOfWork = workInProgressRoot;
deletions = [];
} return [hook.state, setState]
} |
ÉÏÃæ´úÂë¿ÉÒÔ¿´³öÎÒÃÇÔÚ½«useStateºÍ´æ´¢µÄstate½øÐÐÆ¥ÅäµÄʱºòÊÇÓõÄuseStateµÄµ÷ÓÃ˳ÐòÆ¥ÅästateµÄϱ꣬Èç¹ûÕâ¸öÏÂ±êÆ¥Åä²»ÉÏÁË£¬state¾Í´íÁË£¬ËùÒÔReactÀïÃæ²»ÄܳöÏÖÕâÑùµÄ´úÂë:
if (something)
{
const [state, setState] = useState(1);
} |
ÉÏÊö´úÂë²»Äܱ£Ö¤Ã¿´Îsomething¶¼Âú×㣬¿ÉÄܵ¼ÖÂuseStateÕâ´ÎrenderÖ´ÐÐÁË£¬Ï´ÎÓÖûִÐУ¬ÕâÑùÐÂÀϽڵãµÄϱê¾ÍÆ¥Åä²»ÉÏÁË£¬¶ÔÓÚÕâÖÖ´úÂ룬React»áÖ±½Ó±¨´í£º

ÓÃHooksÄ£ÄâClass×é¼þ
Õâ¸ö¹¦ÄÜ´¿´âÊÇÓéÀÖÐÔ¹¦ÄÜ£¬Í¨¹ýÇ°ÃæÊµÏÖµÄHooksÀ´Ä£ÄâʵÏÖClass×é¼þ£¬Õâ¸ö²¢²»ÊÇReact¹Ù·½µÄʵÏÖ·½Ê½¹þ~ÎÒÃÇ¿ÉÒÔдһ¸ö·½·¨½«Class×é¼þת»¯ÎªÇ°ÃæµÄº¯Êý×é¼þ:
function transfer
(Component) {
return function (props) {
const component = new Component(props);
let [state, setState] = useState(component.state);
component.props = props;
component.state = state;
component.setState = setState; return component.render();
}
} |
È»ºó¾Í¿ÉÒÔдClassÁË£¬Õâ¸öClass³¤µÃºÜÏñÎÒÃÇÔÚReactÀïÃæÐ´µÄClass£¬ÓÐstate,setStateºÍrender£º
import React
from './myReact';
class Count4 {
constructor(props) {
this.props = props;
this.state = {
count: 1
}
} onClickHandler = () => {
this.setState({
count: this.state.count + 1
})
} render() {
return (
<div>
<h3>Class component Count: {this.state.count}</h3>
<button onClick= {this.onClickHandler} >Count+1</button>
</div>
);
}
} // exportµÄʱºòÓÃtransfer°ü×°ÏÂ
export default React.transfer (Count4); |
È»ºóʹÓõÄʱºòÖ±½Ó:
<div>
<Count4></Count4> </div> |
µ±È»ÄãÒ²¿ÉÒÔÔÚReactÀïÃæ½¨Ò»¸ö¿ÕµÄclass Component£¬ÈÃCount4¼Ì³ÐËû£¬ÕâÑù¾Í¸üÏñÁË¡£
ºÃÁË£¬µ½ÕâÀïÎÒÃÇ´úÂë¾ÍдÍêÁË£¬ÍêÕû´úÂë¿ÉÒÔ¿´ÎÒGitHub¡£
×ܽá
ÎÒÃÇдµÄJSX´úÂë±»babelת»¯³ÉÁËReact.createElement¡£
React.createElement·µ»ØµÄÆäʵ¾ÍÊÇÐéÄâDOM½á¹¹¡£
ReactDOM.render·½·¨Êǽ«ÐéÄâDOMäÖȾµ½Ò³ÃæµÄ¡£
ÐéÄâDOMµÄµ÷ºÍºÍäÖȾ¿ÉÒÔ¼òµ¥´Ö±©µÄµÝ¹é£¬µ«ÊÇÕâ¸ö¹ý³ÌÊÇͬ²½µÄ£¬Èç¹ûÐèÒª´¦ÀíµÄ½Úµã¹ý¶à£¬¿ÉÄÜ»á×èÈûÓû§ÊäÈëºÍ¶¯»²¥·Å£¬Ôì³É¿¨¶Ù¡£
FiberÊÇ16.xÒýÈëµÄÐÂÌØÐÔ£¬Óô¦Êǽ«Í¬²½µÄµ÷ºÍ±ä³ÉÒì²½µÄ¡£
Fiber¸ÄÔìÁËÐéÄâDOMµÄ½á¹¹£¬¾ßÓи¸ -> µÚÒ»¸ö×Ó£¬×Ó
-> ÐÖ£¬×Ó -> ¸¸Õ⼸¸öÖ¸Õ룬ÓÐÁËÕ⼸¸öÖ¸Õ룬¿ÉÒÔ´ÓÈÎÒâÒ»¸öFiber½ÚµãÕÒµ½ÆäËû½Úµã¡£
Fiber½«Õû¿ÃÊ÷µÄͬ²½ÈÎÎñ²ð·Ö³ÉÁËÿ¸ö½Úµã¿ÉÒÔµ¥¶ÀÖ´ÐеÄÒì²½Ö´Ðнṹ¡£
Fiber¿ÉÒÔ´ÓÈÎÒâÒ»¸ö½Úµã¿ªÊ¼±éÀú£¬±éÀúÊÇÉî¶ÈÓÅÏȱéÀú£¬Ë³ÐòÊǸ¸
-> ×Ó -> ÐÖ -> ¸¸£¬Ò²¾ÍÊÇ´ÓÉÏÍùÏ£¬´Ó×óÍùÓÒ¡£
FiberµÄµ÷ºÍ½×¶Î¿ÉÒÔÊÇÒì²½µÄСÈÎÎñ£¬µ«ÊÇÌá½»½×¶Î(commit)±ØÐëÊÇͬ²½µÄ¡£ÒòΪÒì²½µÄcommit¿ÉÄÜÈÃÓû§¿´µ½½ÚµãÒ»¸öÒ»¸ö½ÓÁ¬³öÏÖ£¬ÌåÑé²»ºÃ¡£
º¯Êý×é¼þÆäʵ¾ÍÊÇÕâ¸ö½ÚµãµÄtypeÊǸöº¯Êý£¬Ö±½Ó½«typeÄÃÀ´ÔËÐоͿÉÒԵõ½ÐéÄâDOM¡£
useStateÊÇÔÚFiber½ÚµãÉÏÌí¼ÓÁËÒ»¸öÊý×飬Êý×éÀïÃæµÄÿ¸öÖµ¶ÔÓ¦ÁËÒ»¸öuseState£¬useStateµ÷ÓÃ˳Ðò±ØÐëºÍÕâ¸öÊý×éÏÂ±êÆ¥Å䣬²»È»»á±¨´í¡£ |