Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
ÊÖдReactµÄFiber¼Ü¹¹£¬ÉîÈëÀí½âÆäÔ­Àí
 
  1484  次浏览      27
 2021-8-12
 
±à¼­ÍƼö:
±¾ÎÄÖ÷Òª´Ó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µ÷ÓÃ˳Ðò±ØÐëºÍÕâ¸öÊý×éÏÂ±êÆ¥Å䣬²»È»»á±¨´í¡£

 
   
1484 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]
 
×îÐÂÎÄÕÂ
ÈçºÎÉè¼Æ¸ßÀ©Õ¹µÄÔÚÏßÍøÒ³ÖÆ×÷ƽ̨
electronÈëÃÅÐĵÃ
ʹÓà Electron ¹¹½¨×ÀÃæÓ¦ÓÃ
VUE.JS×é¼þ»¯¿ª·¢Êµ¼ù
ÉîÈëÀí½âJSCore
×îпγÌ
HTML 5 + CSS3 Ô­ÀíÓ뿪·¢Ó¦ÓÃ
Webǰ¶Ë¸ß¼¶¹¤³Ìʦ±Ø±¸¼¼ÄÜʵս
Vue´óÐÍÏîÄ¿¿ª·¢ÊµÕ½
ReactÔ­ÀíÓëʵ¼ù
Vue.js½ø½×Óë°¸Àýʵ¼ù
³É¹¦°¸Àý
Öн»¼¯ÍÅ ¹¹½¨Web×Ô¶¯»¯²âÊÔ¿ò¼Ü
ijָÃûµçÐŹ«Ë¾ Vue.js½ø½×Óë°¸Àý
¹úµçÍ¨ÍøÂç¼¼Êõ HTML5+CSS3 +webǰ¶Ë¿ò
ÒÆ¶¯Í¨ÐÅ ÒÆ¶¯»¥ÁªÍøÓ¦Óÿª·¢Ô­Àí
ijµçÁ¦ÐÐ android¿ª·¢Æ½Ì¨×î¼Ñ