{"id":413466,"date":"2024-06-29T23:08:34","date_gmt":"2024-06-29T23:08:34","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=413466"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=413466","title":{"rendered":"<span>\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 React: \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/jc\/hw\/st\/jchwst6a3nwlxlscnmuw5tdhmry.png\" data-src=\"https:\/\/habrastorage.org\/webt\/jc\/hw\/st\/jchwst6a3nwlxlscnmuw5tdhmry.png\"\/>  <\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0442, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c, \u0441 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f <code>React<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442? \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043c\u0438\u043d\u0438-\u0432\u0435\u0440\u0441\u0438\u044e <code>React<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import '..\/style.scss' import MyReact from '.\/my-react'  const buttonStyles = {  border: 'none',  outline: 'none',  padding: '0.3rem 0.5rem',  marginLeft: '0.5rem',  backgroundImage: 'linear-gradient(yellow, orange)',  borderRadius: '2px',  boxShadow: '0 1px 2px rgba(0, 0, 0, 0.2)',  cursor: 'pointer' }  \/** @jsx MyReact.createElement *\/ function Counter() {  const [value, setValue] = MyReact.useState(1)  const [count, setCount] = MyReact.useState(1)   return (    &lt;section>      &lt;h1 className='title'>Hello from MyReact!&lt;\/h1>      &lt;div className='box'>        &lt;input          style='width: 80px; padding: 0.15rem 0.5rem;'          type='number'          value={value}          onInput={(e) => {            setValue(Number(e.target.value))          }}        \/>        &lt;button          style={buttonStyles}          onClick={() => {            setCount((count) => count + value)          }}        >          Increment        &lt;\/button>      &lt;\/div>      &lt;h2 className='subtitle'>        Count: &lt;span className='count-value'>{count}&lt;\/span>      &lt;\/h2>      &lt;ul className='list'>        {['React', 'from', 'scratch'].map((item) => (          &lt;li>{item}&lt;\/li>        ))}      &lt;\/ul>    &lt;\/section>  ) }  MyReact.render(&lt;Counter \/>, document.getElementById('app'))<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0432\u044b \u043c\u043e\u0433\u043b\u0438 \u0434\u043e\u0433\u0430\u0434\u0430\u0442\u044c\u0441\u044f, \u043d\u0430\u0448\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f <code>MyReact<\/code>.<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/harryheman\/Blog-Posts\/tree\/master\/react-clone\">\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0421\u043a\u0440\u0438\u043d\u0448\u043e\u0442:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/ba\/bq\/ue\/babque1vl1xr_ib8fsbn4275fzs.png\" data-src=\"https:\/\/habrastorage.org\/webt\/ba\/bq\/ue\/babque1vl1xr_ib8fsbn4275fzs.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0430:<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<div class=\"oembed\">\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/618136d94615593b75e246da\" data-style=\"\" id=\"618136d94615593b75e246da\" width=\"\"><\/div>\n<\/div>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b <a href=\"https:\/\/github.com\/facebook\/react\/tree\/main\/packages\/react\"><code>\u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 React<\/code><\/a>. \u0412\u043c\u0435\u0441\u0442\u0435 \u0441 \u0442\u0435\u043c, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0437\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 2 \u0433\u043e\u0434\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 <code>React<\/code> \u043f\u0440\u0435\u0442\u0435\u0440\u043f\u0435\u043b \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0449\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u044b \u0432 \u043d\u0435\u043c \u043a\u0430\u043a <code>legacy<\/code>. \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u044d\u0442\u043e, \u043e\u0431\u0449\u0438\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b \u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0435\u0436\u043d\u0438\u043c\u0438.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u043f\u043e\u0441\u043b\u0443\u0436\u0438\u043b\u0430 <a href=\"https:\/\/pomb.us\/build-your-own-react\/\">\u044d\u0442\u0430 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c, \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f <a href=\"https:\/\/learn.javascript.ru\/modules\"><code>ES6-\u043c\u043e\u0434\u0443\u043b\u0438<\/code><\/a> \u0438 <a href=\"https:\/\/learn.javascript.ru\/modules\"><code>SASS<\/code><\/a> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/www.snowpack.dev\/\"><code>Snowpack<\/code><\/a>.<\/p>\n<p>  <\/p>\n<h2 id=\"vvedenie\">\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<pre><code class=\"javascript\">const element = &lt;h1 title=\"hello\">Hello from MyReact!&lt;\/h1> const container = document.getElementById(\"root\") ReactDOM.render(element, container)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442?<\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c <code>React-\u044d\u043b\u0435\u043c\u0435\u043d\u0442<\/code>. \u041d\u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u2014 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 <code>DOM-\u044d\u043b\u0435\u043c\u0435\u043d\u0442<\/code>. \u041d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u2014 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c <code>React-\u044d\u043b\u0435\u043c\u0435\u043d\u0442<\/code> \u2014 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0435\u0433\u043e \u0432 <code>container<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u043c\u0435\u043d\u0438\u043c \u043a\u043e\u0434 \u043d\u0430 <code>React<\/code> \u043e\u0431\u044b\u0447\u043d\u044b\u043c <code>JavaScript<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const element = &lt;h1 title=\"hello\">Hello from MyReact!&lt;\/h1><\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u0443 \u043d\u0430\u0441 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/ru.reactjs.org\/docs\/introducing-jsx.html\"><code>JSX<\/code><\/a>.<\/p>\n<p>  <\/p>\n<p><code>JSX<\/code> \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 <code>JS<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0430\u043a\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043a\u0430\u043a <a href=\"https:\/\/babeljs.io\/\"><code>Babel<\/code><\/a>. \u0422\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f, \u043e\u0431\u044b\u0447\u043d\u043e, \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435: \u0437\u0430\u043c\u0435\u043d\u0430 \u043a\u043e\u0434\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u0442\u0435\u0433\u043e\u0432 \u043d\u0430 \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>createElement<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u0433\u0430 (<code>type<\/code>), \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 (<code>props<\/code>) \u0438 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b (<code>children<\/code>). \u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 <code>JSX<\/code> \u0432 <code>JS<\/code> \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0440\u0430\u043d\u0441\u043f\u0438\u043b\u044f\u0446\u0438\u0435\u0439 (transilation).<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const element = React.createElement(  \"h1\",  { title: \"hello\" },  \"Hello from MyReact!\" )<\/code><\/pre>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>React.createElement<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0445 \u0435\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u041d\u0435 \u0441\u0447\u0438\u0442\u0430\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u044d\u0442\u043e \u0432\u0441\u0435, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const element = {  type: \"h1\",  props: {    title: \"hello\",    children: \"Hello from MyReact!\"  } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u2014 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 2 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438: <code>type<\/code> \u0438 <code>props<\/code>. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, <a href=\"https:\/\/github.com\/facebook\/react\/blob\/main\/packages\/react\/src\/ReactElement.js#L147\">\u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u0431\u043e\u043b\u044c\u0448\u0435<\/a>, \u043d\u043e \u043d\u0430\u0441 \u043f\u043e\u043a\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0438.<\/p>\n<p>  <\/p>\n<p><code>type<\/code> \u2014 \u044d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0430\u044f \u0442\u0438\u043f DOM-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c. \u042d\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u0433\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f <code>document.createElement<\/code> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f HTML-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u042d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043e \u0447\u0435\u043c \u043c\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>  <\/p>\n<p><code>props<\/code> \u2014 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0432\u0441\u0435 \u043a\u043b\u044e\u0447\u0438 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 <code>JSX<\/code>. \u041e\u043d \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>children<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>children<\/code> \u2014 \u044d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430, \u043d\u043e, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u044d\u0442\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u0412\u043e\u0442 \u043f\u043e\u0447\u0435\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u2014 \u044d\u0442\u043e \u0434\u0435\u0440\u0435\u0432\u044c\u044f (tree) \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">ReactDOM.render(element, container)<\/code><\/pre>\n<p>  <\/p>\n<p><code>render<\/code> \u2014 \u044d\u0442\u043e \u0442\u043e &#171;\u043c\u0435\u0441\u0442\u043e&#187;, \u0433\u0434\u0435 <code>React<\/code> \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442 <code>DOM<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const node = document.createElement(element.type) node[\"title\"] = element.props.title<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0443\u0437\u0435\u043b (<code>node<\/code>) (\u0432\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u0435 \u043f\u0443\u0442\u0430\u043d\u0438\u0446\u044b \u044f \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u043e\u0432\u043e &#171;\u044d\u043b\u0435\u043c\u0435\u043d\u0442&#187; \u0434\u043b\u044f \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 <code>React<\/code>, \u0430 \u0441\u043b\u043e\u0432\u043e &#171;\u0443\u0437\u0435\u043b&#187; \u2014 \u0434\u043b\u044f \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 <code>DOM<\/code>) \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0442\u0438\u043f\u0430 (<code>type<\/code>) \u2014 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>h1<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u0443\u0437\u043b\u0443 \u0432\u0441\u0435 \u043f\u0440\u043e\u043f\u044b (<code>props<\/code>). \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0443 \u043d\u0430\u0441 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a (<code>title<\/code>).<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const text = document.createTextNode(\"\") text[\"nodeValue\"] = element.props.children<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0443\u0437\u043b\u044b \u0434\u043b\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0443 \u043d\u0430\u0441 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0442\u0430\u043a\u043e\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u2014 \u0441\u0442\u0440\u043e\u043a\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0443\u0437\u0435\u043b.<\/p>\n<p>  <\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <code>nodeValue<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>innerText<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c <code>nodeValue<\/code> \u0442\u0430\u043a, \u043a\u0430\u043a \u0435\u0441\u043b\u0438 \u0431\u044b \u0441\u0442\u0440\u043e\u043a\u0430 \u0438\u043c\u0435\u043b\u0430 <code>props: { nodeValue: \"Hello from MyReact!\" }<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">node.append(text) container.append(node)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c <code>textNode<\/code> \u0432 <code>h1<\/code>, \u0430 <code>h1<\/code> \u0432 <code>container<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const element = {  type: \"h1\",  props: {    title: \"hello\",    children: \"Hello from MyReact!\"  } }  const container = document.getElementById(\"root\")  const node = document.createElement(element.type) node[\"title\"] = element.props.title  const text = document.createTextNode(\"\") text[\"nodeValue\"] = element.props.children  node.append(text) container.append(node)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u0434, \u043d\u043e \u0431\u0435\u0437 <code>React<\/code>.<\/p>\n<p>  <\/p>\n<h2 id=\"funkciya-createelement\">\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>createElement<\/code><\/h2>\n<p>  <\/p>\n<pre><code class=\"javascript\">const element = (  &lt;section id=\"welcome\">    &lt;h1 title=\"hello\" className=\"title\">Hello from MyReact!&lt;\/h1>    &lt;p style=\"color: green;\">&lt;span>React&lt;\/span> from scratch&lt;\/p>  &lt;\/section> ) const container = document.getElementById(\"root\") ReactDOM.render(element, container)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>createElement<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c <code>JSX<\/code> \u0432 <code>JS<\/code>, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const element = React.createElement(  \"section\",  { id: \"welcome\" },  React.createElement(    \"h1\",    { title: \"hello\", className: \"title\" },    \"Hello from MyReact!\"  ),  React.createElement(    \"p\",    { style: \"color: green;\" },    React.createElement(      \"span\",      null,      \"React\"    )    \" from scratch\"  ) )<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043c\u044b \u0432\u044b\u044f\u0441\u043d\u0438\u043b\u0438, \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u2014 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 <code>type<\/code> \u0438 <code>props<\/code>. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u0430\u0448\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function createElement(type, props, ...children) {  return {    type,    props: {      ...props,      children,    }  } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b <code>spread<\/code> \u0434\u043b\u044f <code>props<\/code> \u0438 <a href=\"https:\/\/learn.javascript.ru\/rest-parameters-spread-operator\"><code>rest<\/code><\/a> \u0434\u043b\u044f <code>children<\/code> (\u043f\u043e\u044d\u0442\u043e\u043c\u0443 <code>children<\/code> \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c).<\/p>\n<p>  <\/p>\n<p><code>createElement(\"section\")<\/code> \u0432\u0435\u0440\u043d\u0435\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">{  type: \"section\",  props: {    children: []  } }<\/code><\/pre>\n<p>  <\/p>\n<p><code>createElement(\"section\", null, \"hello\")<\/code> \u0432\u0435\u0440\u043d\u0435\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">{  type: \"section\",  props: {    children: [\"hello\"]  } }<\/code><\/pre>\n<p>  <\/p>\n<p><code>createElement(\"section\", { title: \"hello\" }, \"hello\", \"world\")<\/code> \u0432\u0435\u0440\u043d\u0435\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">{  type: \"section\",  props: {    title: \"hello\",    children: [      \"hello\",      \"world\"    ]  } }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"javascript\">function createElement(type, props, ...children) {  return {    type,    props: {      ...props,      \/\/ ! - \u0437\u0434\u0435\u0441\u044c \u0438 \u0434\u0430\u043b\u0435\u0435 \u0442\u0430\u043a \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u044b \u0432\u043d\u043e\u0441\u0438\u043c\u044b\u0435 \u0432 \u043a\u043e\u0434 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f      children: children.map(child =>        typeof child === \"object\"          ? child          : createTextElement(child)      )    }  } }  function createTextElement(nodeValue) {  return {    type: \"TEXT_ELEMENT\",    props: {      nodeValue,      children: []    }  } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u0430\u0441\u0441\u0438\u0432 <code>children<\/code> \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u043b\u0438 \u0447\u0438\u0441\u043b\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0441 \u0442\u0438\u043f\u043e\u043c, \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0449\u0438\u043c\u0441\u044f \u043e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0441\u043e\u0437\u0434\u0430\u044e\u0449\u0430\u044f \u043e\u0441\u043e\u0431\u044b\u0439 \u0442\u0438\u043f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430: <code>TEXT_ELEMENT<\/code>.<\/p>\n<p>  <\/p>\n<p><code>React<\/code> \u043d\u0435 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b \u0438 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043f\u0443\u0441\u0442\u044b\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 <code>children<\/code>. \u041c\u044b \u0436\u0435\u0440\u0442\u0432\u0443\u0435\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0434\u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043a\u043e\u0434\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const MyReact = {  createElement }  const element = MyReact.createElement(  \"section\",  { id: \"welcome\" },  MyReact.createElement(    \"h1\",    { title: \"hello\", className: \"title\" },    \"Hello from MyReact!\"  ),  MyReact.createElement(    \"p\",    { style: \"color: green;\" },    MyReact.createElement(      \"span\",      null,      \"React\"    )    \" from scratch\"  ) )<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u043c\u0435\u043d\u044f\u0435\u043c <code>React<\/code> \u043d\u0430 <code>MyReact<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>JSX<\/code>, \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c <code>Babel<\/code> \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 <code>JSX<\/code> \u0432 \u043d\u0430\u0448\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>createElement<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/** @jsx MyReact.createElement *\/ const element = (  &lt;section id=\"welcome\">    &lt;h1 title=\"hello\" className=\"title\">Hello from MyReact!&lt;\/h1>    &lt;p style=\"color: green;\">&lt;span>React&lt;\/span> from scratch&lt;\/p>  &lt;\/section> )<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 <code>\/** @jsx MyReact.createElement *\/<\/code> \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 <code>Babel<\/code> \u043e \u043d\u0430\u0448\u0435\u043c \u0436\u0435\u043b\u0430\u043d\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e <code>createElement<\/code> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>  <\/p>\n<h2 id=\"funkciya-render\">\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>render<\/code><\/h2>\n<p>  <\/p>\n<pre><code class=\"javascript\">ReactDOM.render(element, container)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <a href=\"https:\/\/github.com\/facebook\/react\/blob\/main\/packages\/react-dom\/src\/client\/ReactDOMLegacy.js#L266\"><code>ReactDOM.render<\/code><\/a>.<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0443\u0437\u043b\u043e\u0432 \u0432 <code>DOM<\/code>, \u0430 \u0438\u0445 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function render(element, container) {  const node = document.createElement(element.type) \u200b  container.append(node) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0443\u0437\u0435\u043b \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0442\u0438\u043f\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function render(element, container) {  const node = document.createElement(element.type) \u200b  \/\/ !  element.props.children.forEach(child =>    render(child, node)  ) \u200b  container.appendChild(node) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043c\u043a\u0430 \u0443\u0437\u043b\u0430 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function render(element, container) {  \/\/ !  const node =    element.type == \"TEXT_ELEMENT\"      ? document.createTextNode(\"\")      : document.createElement(element.type) \u200b  element.props.children.forEach(child =>    render(child, node)  ) \u200b  container.appendChild(node) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0442\u0438\u043f\u043e\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>TEXT_ELEMENT<\/code>, \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function render(element, container) {  const node =    element.type == \"TEXT_ELEMENT\"      ? document.createTextNode(\"\")      : document.createElement(element.type)   \/\/ !  const isProperty = key => key !== \"children\"  Object.keys(element.props)    .filter(isProperty)    .forEach(key => {      node[key] = element.props[key]    }) \u200b  element.props.children.forEach(child =>    render(child, node)  ) \u200b  container.appendChild(node) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u044d\u0442\u043e \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u0443\u0437\u043b\u0443 \u043f\u0440\u043e\u043f\u044b \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function createElement(type, props, ...children) {  return {    type,    props: {      ...props,      children: children.map(child =>        typeof child === \"object\"          ? child          : createTextElement(child)      )    }  } }  function createTextElement(nodeValue) {  return {    type: \"TEXT_ELEMENT\",    props: {      nodeValue,      children: [],    }  } }  function render(element, container) {  const node =    element.type == \"TEXT_ELEMENT\"      ? document.createTextNode(\"\")      : document.createElement(element.type)   const isProperty = key => key !== \"children\"  Object.keys(element.props)    .filter(isProperty)    .forEach(key => {      node[key] = element.props[key]    }) \u200b  element.props.children.forEach(child =>    render(child, node)  ) \u200b  container.appendChild(node) }  const MyReact = {  createElement,  render }  \/** @jsx MyReact.createElement *\/ const element = (  &lt;section id=\"welcome\">    &lt;h1 title=\"hello\" className=\"title\">Hello from MyReact!&lt;\/h1>    &lt;p style=\"color: green;\">&lt;span>React&lt;\/span> from scratch&lt;\/p>  &lt;\/section> )  const container = document.getElementById(\"root\") MyReact.render(element, container)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u0430\u043c\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 (\u0438 \u0434\u0440\u0443\u0433\u0438\u0435):<\/p>\n<p>  <\/p>\n<pre><code class=\"html\">&lt;!-- index.html -->  &lt;div id=\"root\">&lt;\/div>  &lt;script src=\"https:\/\/unpkg.com\/@babel\/standalone\/babel.min.js\">&lt;\/script> &lt;script type=\"text\/babel\">  \/\/ MyReact &lt;\/script><\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"konkurentnyy-rezhim-concurrent-mode\">\u041a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c (Concurrent Mode)<\/h2>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u043c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u0432\u0435\u0441\u0435\u043b\u0438\u0442\u044c\u0441\u044f, \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 \u043a\u043e\u0434\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">element.props.children.forEach(child =>  render(child, node) )<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0447\u0435\u043c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430? (\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0432\u044b \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u0435 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0443 \u0432 <code>Facebook<\/code> \ud83d\ude09 )<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">   .  .     \\\/    (@@) g\/\\_)(_\/\\e g\/\\(=--=)\/\\e    \/\/\\\\   _|  |_<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u043c\u044b \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u0432\u0441\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0446\u0435\u043b\u0438\u043a\u043e\u043c. \u0415\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435, \u0435\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b (main thread) \u043d\u0430 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f. \u0415\u0441\u043b\u0438 \u0443 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0432 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u044f\u0432\u044f\u0442\u0441\u044f \u0432\u0430\u0436\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u0432\u0440\u043e\u0434\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0432\u043e\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0432\u0432\u0438\u0434\u0443 \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u0435\u0439 \u0444\u043e\u0440\u043c\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440) \u0438\u043b\u0438 \u043f\u043b\u0430\u0432\u043d\u043e\u0435 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438, \u043e\u043d \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u044d\u0442\u043e\u0433\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">let nextUnitOfWork = null \u200b function workLoop(deadline) {  while (nextUnitOfWork &amp;&amp; deadline.timeRemaining() > 0) {    nextUnitOfWork = performUnitOfWork(nextUnitOfWork)  }   requestIdleCallback(workLoop) } \u200b requestIdleCallback(workLoop)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043d\u0430 \u0447\u0430\u0441\u0442\u0438. \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u0432\u043e\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 (\u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0442\u0430\u043a\u043e\u0432\u044b\u0445).<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/Window\/requestIdleCallback\"><code>requestIdleCallback<\/code><\/a> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430. <code>requestIdleCallback<\/code> \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 <code>setTimeout<\/code>, \u043d\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u0447\u0435\u0440\u0435\u0437 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 (\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>workLoop<\/code>), \u043a\u043e\u0433\u0434\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u0441\u0432\u043e\u0431\u043e\u0434\u0435\u043d \u043e\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 (\u043f\u0435\u0440\u0438\u043e\u0434 \u043f\u0440\u043e\u0441\u0442\u043e\u044f \u0438\u043b\u0438 \u0440\u0435\u0436\u0438\u043c \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u2014 \u043e\u0442\u0441\u044e\u0434\u0430 <code>idle<\/code>).<\/p>\n<p>  <\/p>\n<p>\u0412 <code>React<\/code> \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>requestIdleCallback<\/code>. \u0422\u0435\u043f\u0435\u0440\u044c \u0442\u0430\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/github.com\/facebook\/react\/tree\/main\/packages\/scheduler\"><code>scheduler<\/code><\/a>. \u041f\u043e \u0432\u0441\u0435\u0439 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u044d\u0442\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e <code>requestIdleCallback<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0435\u0439 \u0438 <a href=\"https:\/\/caniuse.com\/requestidlecallback\">\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u0432\u0441\u0435\u043c\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u043c\u0438<\/a>. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, <code>Safari<\/code> \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 <code>requestIdleCallback<\/code> \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u0441\u0442\u0440\u0430\u0445\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 <code>requestIdleCallback<\/code> \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">window.requestIdleCallback =  window.requestIdleCallback ||  function (handler) {    const start = Date.now()     return setTimeout(() => {      handler({        didTimeout: false,        timeRemaining: () => Math.max(0, 50 - (Date.now() - start))      })    }, 1)  }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e <code>requestIdleCallback<\/code> \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Background_Tasks_API\">\u0437\u0434\u0435\u0441\u044c<\/a> \u0438 <a href=\"https:\/\/developers.google.com\/web\/updates\/2015\/08\/using-requestidlecallback\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function performUnitOfWork(nextUnitOfWork) {  \/\/ TODO }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0446\u0438\u043a\u043b, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u0443\u044e \u0435\u0434\u0438\u043d\u0438\u0446\u0443 \u0440\u0430\u0431\u043e\u0442\u044b. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0435\u0449\u0435 \u043e\u0434\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u2014 <code>performUnitOfWork<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0435\u0434\u0438\u043d\u0438\u0446\u0443 \u0440\u0430\u0431\u043e\u0442\u044b, \u043d\u043e \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e.<\/p>\n<p>  <\/p>\n<h2 id=\"volokno-fiber\">\u0412\u043e\u043b\u043e\u043a\u043d\u043e (Fiber)<\/h2>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0435\u0434\u0438\u043d\u0438\u0446\u0430\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445. \u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0442\u0430\u043a\u0438\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>fiber tree<\/code> (\u0443\u0441\u043b\u043e\u0432\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u043a\u0430\u043a &#171;\u0434\u0440\u0435\u0432\u0435\u0441\u043d\u043e\u0435 \u0432\u043e\u043b\u043e\u043a\u043d\u043e&#187;).<\/p>\n<p>  <\/p>\n<p>\u0423 \u043d\u0430\u0441 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e \u0432\u043e\u043b\u043e\u043a\u043d\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438 \u043a\u0430\u0436\u0434\u043e\u0435 \u0432\u043e\u043b\u043e\u043a\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u0443 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/nz\/c0\/e2\/nzc0e2rr7omhkxuadfm2i23almm.png\" data-src=\"https:\/\/habrastorage.org\/webt\/nz\/c0\/e2\/nzc0e2rr7omhkxuadfm2i23almm.png\"\/>  <\/p>\n<p>  \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">MyReact.render(  &lt;section>    &lt;h1>      &lt;p>&lt;\/p>      &lt;a>&lt;\/a>    &lt;\/h1>    &lt;h2>&lt;\/h2>  &lt;\/section>,  container )<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0435 <code>render<\/code> \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0435 \u0432\u043e\u043b\u043e\u043a\u043d\u043e (root fiber) \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <code>nextUnitOfWork<\/code>. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>performUnitOfWork<\/code>. \u0422\u0430\u043c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 3 \u0432\u0435\u0449\u0438:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 <code>DOM<\/code><\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u043e\u043b\u043e\u043a\u043e\u043d \u0434\u043b\u044f \u043f\u043e\u0442\u043e\u043c\u043a\u043e\u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430<\/li>\n<li>\u0412\u044b\u0431\u043e\u0440 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u044b \u0440\u0430\u0431\u043e\u0442\u044b<\/li>\n<\/ol>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/9i\/n_\/un\/9in_unu7qyjhug2p8y81pjggram.png\" data-src=\"https:\/\/habrastorage.org\/webt\/9i\/n_\/un\/9in_unu7qyjhug2p8y81pjggram.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0437\u0430\u0434\u0430\u0447 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u044b \u0440\u0430\u0431\u043e\u0442\u044b. \u0412\u043e\u0442 \u043f\u043e\u0447\u0435\u043c\u0443 \u043a\u0430\u0436\u0434\u043e\u0435 \u0432\u043e\u043b\u043e\u043a\u043d\u043e \u0438\u043c\u0435\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043c\u043a\u0430 (<code>child<\/code>), <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BD%D0%B3%D0%B8\">\u0441\u0438\u0431\u043b\u0438\u043d\u0433\u0430<\/a> (<code>sibling<\/code>) \u0438 \u043f\u0440\u0435\u0434\u043a\u0430 (<code>parent<\/code>).<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u043e\u043b\u043e\u043a\u043d\u0430, \u0435\u0441\u043b\u0438 \u0443 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c <code>child<\/code>, \u043e\u043d \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438 \u0441 <code>section<\/code>, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f <code>h1<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u043e\u043b\u043e\u043a\u043d\u043e \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 <code>child<\/code>, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f <code>sibling<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u043b\u043e\u043a\u043d\u043e <code>p<\/code> \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 <code>child<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f <code>a<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0435\u0441\u043b\u0438 \u0432\u043e\u043b\u043e\u043a\u043d\u043e \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043d\u0438 <code>child<\/code>, \u043d\u0438 <code>sibling<\/code>, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f <code>sibling<\/code> \u043f\u0440\u0435\u0434\u043a\u0430 \u0432\u043e\u043b\u043e\u043a\u043d\u0430 (<code>parent<\/code>).<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 <code>parent<\/code> \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 <code>sibling<\/code>, \u043c\u044b \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c\u0441\u044f \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 <code>parent<\/code> \u0438 \u0442\u0430\u043a \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0435\u043c \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e \u0432\u043e\u043b\u043e\u043a\u043d\u0430. \u0415\u0441\u043b\u0438 \u043c\u044b \u0434\u043e\u0441\u0442\u0438\u0433\u043b\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u0432\u043e\u043b\u043e\u043a\u043d\u0430, \u0437\u043d\u0430\u0447\u0438\u0442, \u0440\u0430\u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 <code>render<\/code> \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function createNode(fiber) {  const node =    fiber.type == \"TEXT_ELEMENT\"      ? document.createTextNode(\"\")      : document.createElement(fiber.type) \u200b  const isProperty = key => key !== \"children\"  Object.keys(fiber.props)    .filter(isProperty)    .forEach(key => {      node[key] = fiber.props[key]    }) \u200b  return node }  function render(element, container) {  \/\/ TODO }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u044b\u043d\u0435\u0441\u0435\u043c \u043a\u043e\u0434 \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0443\u0437\u043b\u043e\u0432 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>render<\/code> \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043e\u043d \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430\u043c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function render(element, container) {  nextUnitOfWork = {    node: container,    props: {      children: [element]    }  } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>render<\/code> \u043c\u044b \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c <code>nextUnitOfWork<\/code> \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0443\u0437\u0435\u043b <code>fiber tree<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">nextUnitOfWork = performUnitOfWork(  nextUnitOfWork )<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432, \u043e\u043d \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442 &#171;\u043a\u043e\u043b\u0431\u0435\u043a&#187; <code>workLoop<\/code> \u0438 \u043d\u0430\u0447\u043d\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e \u0443\u0437\u043b\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function performUnitOfWork(fiber) {  if (!fiber.node) {    fiber.node = createNode(fiber)  } \u200b  if (fiber.parent) {    fiber.parent.node.append(fiber.node)  } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0443\u0437\u0435\u043b \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u0432 <code>DOM<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0423\u0437\u043b\u044b \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0435 <code>fiber.node<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const elements = fiber.props.children let index = 0 let prevSibling = null \u200b while (index &lt; elements.length) {  const element = elements[index] \u200b  const newFiber = {    type: element.type,    props: element.props,    parent: fiber,    node: null  } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043c\u043a\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0432\u043e\u043b\u043e\u043a\u043d\u043e.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const elements = fiber.props.children let index = 0 let prevSibling = null \u200b while (index &lt; elements.length) {  const element = elements[index] \u200b  const newFiber = {    type: element.type,    props: element.props,    parent: fiber,    node: null,  } \u200b  \/\/ !  \/\/ \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043c\u043e\u043a?  if (index === 0) {    \/\/ \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u043f\u0440\u0435\u0434\u043a\u0430    fiber.child = newFiber  } else {    \/\/ \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0432\u043e\u043b\u043e\u043a\u043d\u0430    prevSibling.sibling = newFiber  } \u200b  prevSibling = newFiber  index++ }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u043e\u0432\u043e\u0435 \u0432\u043e\u043b\u043e\u043a\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <code>fiber tree<\/code> \u043b\u0438\u0431\u043e \u043a\u0430\u043a <code>child<\/code>, \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u043c \u043f\u043e\u0442\u043e\u043c\u043a\u043e\u043c, \u043b\u0438\u0431\u043e \u043a\u0430\u043a <code>sibling<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const elements = fiber.props.children let index = 0 let prevSibling = null \u200b while (index &lt; elements.length) {  const element = elements[index] \u200b  const newFiber = {    type: element.type,    props: element.props,    parent: fiber,    node: null,  } \u200b  if (index === 0) {    fiber.child = newFiber  } else {    prevSibling.sibling = newFiber  } \u200b  prevSibling = newFiber  index++ }  \/\/ ! \/\/ \u0435\u0441\u0442\u044c \u043f\u043e\u0442\u043e\u043c\u043e\u043a? if (fiber.child) {  return fiber.child }  let nextFiber = fiber while (nextFiber) {  \/\/ \u0435\u0441\u0442\u044c \u0441\u0438\u0431\u043b\u0438\u043d\u0433?  if (nextFiber.sibling) {    return nextFiber.sibling  }   \/\/ \u0441\u043f\u0440\u043e\u0441\u0438\u043c \u0443 \u043f\u0440\u0435\u0434\u043a\u0430  nextFiber = nextFiber.parent }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0435\u0434\u0438\u043d\u0438\u0446\u0443 \u0440\u0430\u0431\u043e\u0442\u044b. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043c\u043a\u0430. \u0415\u0441\u043b\u0438 \u043f\u043e\u0442\u043e\u043c\u043e\u043a \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0441\u0438\u0431\u043b\u0438\u043d\u0433. \u0415\u0441\u043b\u0438 \u0441\u0438\u0431\u043b\u0438\u043d\u0433\u0430 \u043d\u0435\u0442, \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c\u0441\u044f \u043a \u043f\u0440\u0435\u0434\u043a\u0443 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0435\u0433\u043e \u0441\u0438\u0431\u043b\u0438\u043d\u0433\u0430 \u0438 \u0442.\u0434.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function performUnitOfWork(fiber) {  if (!fiber.node) {    fiber.node = createNode(fiber)  } \u200b  if (fiber.parent) {    fiber.parent.node.append(fiber.node)  }   const elements = fiber.props.children  let index = 0  let prevSibling = null  \u200b  while (index &lt; elements.length) {    const element = elements[index]  \u200b    const newFiber = {      type: element.type,      props: element.props,      parent: fiber,      node: null,    }  \u200b    if (index === 0) {      fiber.child = newFiber    } else {      prevSibling.sibling = newFiber    }  \u200b    prevSibling = newFiber    index++  }   if (fiber.child) {    return fiber.child  }   let nextFiber = fiber  while (nextFiber) {    if (nextFiber.sibling) {      return nextFiber.sibling    }     nextFiber = nextFiber.parent  } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0430\u0448\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>performUnitOfWork<\/code>.<\/p>\n<p>  <\/p>\n<h2 id=\"etapy-renderinga-i-fiksacii-rezultatov-commit\">\u042d\u0442\u0430\u043f\u044b \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0438 \u0444\u0438\u043a\u0441\u0430\u0446\u0438\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 (Commit)<\/h2>\n<p>  <\/p>\n<pre><code class=\"javascript\">if (fiber.parent) {  fiber.parent.node.append(fiber.node) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0447\u0435\u043c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u044d\u0442\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u043a\u043e\u0434\u0430? (\u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u0438\u0437 100 \ud83d\ude09 )<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">   o   o     )-(    (O O)     \\=\/    .-\"-.   \/\/\\ \/\\\\ _\/\/ \/ \\ \\\\_ =.\/ {,-.} \\.=    || ||    || ||  __|| ||__ `---\" \"---'<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0443\u0437\u0435\u043b \u0432 <code>DOM<\/code> \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 (\u0432\u043e\u043b\u043e\u043a\u043d\u0430). \u041a\u0430\u043a \u043c\u044b \u043f\u043e\u043c\u043d\u0438\u043c, \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0438\u0445 \u0437\u0430\u0434\u0430\u0447. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u044b \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043b\u0438 \u0432\u0441\u0435 \u0434\u0435\u0440\u0435\u0432\u043e. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u2014 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0438\u0434\u0438\u0442 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0439 <code>UI<\/code>. \u042d\u0442\u043e \u043d\u0435 \u0435\u0441\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u043e.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0430\u0441\u0442\u044c, \u043c\u0443\u0442\u0438\u0440\u0443\u044e\u0449\u0443\u044e <code>DOM<\/code>, \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>performUnitOfWork<\/code> \u043c\u044b \u0443\u0434\u0430\u043b\u044f\u0435\u043c.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function render(element, container) {  \/\/ !  workingRoot = {    node: container,    props: {      children: [element]    }  }   \/\/ !  nextUnitOfWork = workingRoot } \u200b let nextUnitOfWork = null \/\/ ! let workingRoot = null<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e, \u043c\u044b \u0441\u043b\u0435\u0434\u0438\u043c \u0437\u0430 \u043a\u043e\u0440\u043d\u0435\u043c <code>fiber tree<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\"> function workLoop(deadline) {  \/\/ ... \u200b  if (!nextUnitOfWork &amp;&amp; workingRoot) {    requestAnimationFrame(commitRoot)  } \u200b  \/\/ ... }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b (\u044d\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u044b \u0440\u0430\u0431\u043e\u0442\u044b) \u043c\u044b \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c (commit) <code>fiber tree<\/code>, \u0442.\u0435. \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u0432 <code>DOM<\/code> (\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c).<\/p>\n<p>  <\/p>\n<p>\u041e \u0442\u043e\u043c, \u043f\u043e\u0447\u0435\u043c\u0443 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0437\u0434\u0435\u0441\u044c <code>requestAnimationFrame<\/code> \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430\u0445, \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u043d\u044b\u043c <code>requestIdleCallback<\/code>, \u043f\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u043c \u0432\u044b\u0448\u0435 \u0441\u0441\u044b\u043b\u043a\u0430\u043c. <a href=\"https:\/\/stackoverflow.com\/questions\/41740082\/scroll-events-requestanimationframe-vs-requestidlecallback-vs-passive-event-lis\"><code>\u041e\u0442\u043b\u0438\u0447\u043d\u043e\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043d\u0438\u0446\u044b \u043c\u0435\u0436\u0434\u0443 rAF<\/code> \u0438 <code>rIC<\/code> \u043d\u0430 <code>Stack Overflow<\/code><\/a>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function commitRoot() {  commitWork(workingRoot.child)  workingRoot = null } \u200b function commitWork(fiber) {  if (!fiber) {    return  }   const parentNode = fiber.parent.node  parentNode.append(fiber.node)   commitWork(fiber.child)  commitWork(fiber.sibling) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>commitRoot<\/code>. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0441\u0435 \u0443\u0437\u043b\u044b \u0432 <code>DOM<\/code>.<\/p>\n<p>  <\/p>\n<h2 id=\"soglasovanie-reconcilation\">\u0421\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u0435 (Reconcilation)<\/h2>\n<p>  <\/p>\n<p>\u0414\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0438 \u0443\u0437\u043b\u044b \u0432 <code>DOM<\/code>. \u041d\u043e \u0447\u0442\u043e \u043d\u0430\u0441\u0447\u0435\u0442 \u0438\u0445 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f?<\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u0438\u043c \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0438 \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f. \u041d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>render<\/code> \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c <code>fiber tree<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0432 <code>DOM<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function commitRoot() {  commitWork(workingRoot.child)  \/\/ !  currentRoot = workingRoot  workingRoot = null }  function render(element, container) {  workingRoot = {    dom: container,    props: {      children: [element],    },    \/\/ !    alternate: currentRoot,  }  nextUnitOfWork = workingRoot }  let nextUnitOfWork = null \/\/ ! let currentRoot = null let workingRoot = null<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 <code>fiber tree<\/code> \u043f\u043e\u0441\u043b\u0435 \u0444\u0438\u043a\u0441\u0430\u0446\u0438\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0435 <code>currentRoot<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0432\u043e\u043b\u043e\u043a\u043d\u0443 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>alternate<\/code>. \u0414\u0430\u043d\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u2014 \u044d\u0442\u043e \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u0442\u0430\u0440\u043e\u0435 \u0432\u043e\u043b\u043e\u043a\u043d\u043e, \u0432\u043e\u043b\u043e\u043a\u043d\u043e, \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0432 <code>DOM<\/code> \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0434\u0438\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function performUnitOfWork(fiber) {  \/\/ ... \u200b  const elements = fiber.props.children  \/\/ !  reconcileChildren(fiber, elements) \u200b  if (fiber.child) {    return fiber.child  }  \/\/ ... }  function reconcileChildren(workingFiber, elements) {  let index = 0  let prevSibling = null \u200b  while (index &lt; elements.length) {    const element = elements[index] \u200b    const newFiber = {      type: element.type,      props: element.props,      parent: workingFiber,      node: null,    } \u200b    if (index === 0) {      workingFiber.child = newFiber    } else {      prevSibling.sibling = newFiber    } \u200b    prevSibling = newFiber    index++  } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0432\u043e\u043b\u043e\u043a\u043e\u043d \u0438\u0437 <code>performUnitOfWork<\/code> \u0432 \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>reconcileChildren<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0435 \u0432\u043e\u043b\u043e\u043a\u043d\u0430 \u0441 \u043d\u043e\u0432\u044b\u043c\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function reconcileChildren(workingFiber, elements) {  let index = 0  let oldFiber =    workingFiber.alternate &amp;&amp; workingFiber.alternate.child  let prevSibling = null \u200b  while (    index &lt; elements.length ||    oldFiber !== null  ) {    \/\/ TODO  } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043c\u043a\u043e\u0432 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0432\u043e\u043b\u043e\u043a\u043d\u0430 (<code>workingFiber.alternate<\/code>) \u0438 \u043c\u0430\u0441\u0441\u0438\u0432 \u043d\u043e\u0432\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u043e\u043f\u0443\u0441\u0442\u0438\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0443 \u0438 \u0441\u0432\u044f\u0437\u043d\u043e\u043c\u0443 \u0441\u043f\u0438\u0441\u043a\u0443, \u0442\u043e \u0443 \u043d\u0430\u0441 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f 2 \u0432\u0435\u0449\u0438: <code>oldFiber<\/code> \u0438 <code>element<\/code>. <code>element<\/code> \u2014 \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0432 <code>DOM<\/code>, \u0430 <code>oldFiber<\/code> \u2014 \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043b\u043e\u0441\u044c \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0445 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043a <code>DOM<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const element = elements[index] let newFiber = null  const sameType =  oldFiber &amp;&amp;  element &amp;&amp;  element.type == oldFiber.type \u200b if (sameType) {  \/\/ TODO \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0443\u0437\u0435\u043b } if (element &amp;&amp; !sameType) {  \/\/ TODO \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0443\u0437\u0435\u043b } if (oldFiber &amp;&amp; !sameType) {  \/\/ TODO \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0443\u0437\u0435\u043b }  if (oldFiber) {  oldFiber = oldFiber.sibling }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0438\u0445 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u0438\u043f:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0435\u0441\u043b\u0438 \u0441\u0442\u0430\u0440\u043e\u0435 \u0432\u043e\u043b\u043e\u043a\u043d\u043e \u0438 \u043d\u043e\u0432\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438\u043c\u0435\u044e\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0442\u0438\u043f, \u043c\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0443\u0437\u0435\u043b \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u043d\u043e\u0432\u044b\u043c\u0438 \u043f\u0440\u043e\u043f\u0430\u043c\u0438<\/li>\n<li>\u0435\u0441\u043b\u0438 \u0442\u0438\u043f\u044b \u0440\u0430\u0437\u043d\u044b\u0435 \u0438 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0443\u0437\u0435\u043b<\/li>\n<li>\u0435\u0441\u043b\u0438 \u0442\u0438\u043f\u044b \u0440\u0430\u0437\u043d\u044b\u0435 \u0438 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0440\u043e\u0435 \u0432\u043e\u043b\u043e\u043d\u043a\u043e, \u043c\u044b \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0443\u0437\u0435\u043b<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c <code>React<\/code> \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043a\u043b\u044e\u0447\u0438 (keys) \u0432 \u0446\u0435\u043b\u044f\u0445 \u043b\u0443\u0447\u0448\u0435\u0433\u043e \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043b\u044e\u0447\u0435\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">if (sameType) {  newFiber = {    type: oldFiber.type,    props: element.props,    node: oldFiber.node,    parent: workingFiber,    alternate: oldFiber,    action: \"UPDATE\",  } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0441\u0442\u0430\u0440\u043e\u0435 \u0432\u043e\u043b\u043e\u043a\u043d\u043e \u0438 \u043d\u043e\u0432\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438\u043c\u0435\u044e\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0442\u0438\u043f, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u043e\u0435 \u0432\u043e\u043b\u043e\u043a\u043d\u043e, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044f \u0443\u0437\u0435\u043b \u0438\u0437 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0432\u043e\u043b\u043e\u043a\u043d\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044f \u043f\u0440\u043e\u043f\u044b \u0438\u0437 \u043d\u043e\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430.<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0432\u043e\u043b\u043e\u043a\u043d\u043e \u043d\u043e\u0432\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>action<\/code> (\u0432 <code>React<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 <code>effectTag<\/code>). \u042d\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u0442\u0430\u0434\u0438\u0438 \u0444\u0438\u043a\u0441\u0430\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">if (element &amp;&amp; !sameType) {  newFiber = {    type: element.type,    props: element.props,    node: null,    parent: workingFiber,    alternate: null,    action: \"ADD\",  } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0443\u0437\u043b\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>action: \"ADD\"<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">if (oldFiber &amp;&amp; !sameType) {  oldFiber.action = \"REMOVE\"  nodesToRemove.push(oldFiber) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435, \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439 \u0443\u0437\u0435\u043b, \u043d\u043e\u0432\u043e\u0433\u043e \u0432\u043e\u043b\u043e\u043a\u043d\u0430 \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>action<\/code> \u043a \u0441\u0442\u0430\u0440\u043e\u043c\u0443 \u0432\u043e\u043b\u043e\u043a\u043d\u0443.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c <code>fiber tree<\/code> \u0432 <code>DOM<\/code>, \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e (\u0438\u0437) <code>workingRoot<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u0442\u0430\u0440\u044b\u0445 \u0432\u043e\u043b\u043e\u043a\u043e\u043d.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function render(element, container) {  workingRoot = {    dom: container,    props: {      children: [element],    },    alternate: currentRoot,  }  \/\/ !  nodesToRemove = []  nextUnitOfWork = workingRoot } \u200b let nextUnitOfWork = null let currentRoot = null let workingRoot = null \/\/ ! let nodesToRemove = null<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u043c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u0443\u0437\u043b\u043e\u0432, \u043f\u043e\u0434\u043b\u0435\u0436\u0430\u0449\u0438\u0445 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044e.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function commitRoot() {  \/\/ !  nodesToRemove.forEach(commitWork)  commitWork(workingRoot.child)  currentRoot = workingRoot  workingRoot = null }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u044d\u0442\u043e\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0440\u0438 \u0444\u0438\u043a\u0441\u0430\u0446\u0438\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>commitWork<\/code> \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u043c <code>parentNode.append(fiber.node)<\/code> \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">switch (fiber.action) {  case 'ADD':    fiber.node &amp;&amp; parentNode.append(fiber.node)    break  case 'REMOVE':    fiber.node.remove()    break  case 'UPDATE':    fiber.node &amp;&amp; updateNode(fiber.node, fiber.alternate.props, fiber.props)    break  default:    return }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 <code>fiber.action<\/code> \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>ADD<\/code>, \u043c\u044b \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0443\u0437\u0435\u043b \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0443\u0437\u0435\u043b. \u0415\u0441\u043b\u0438 <code>fiber.action<\/code> \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>REMOVE<\/code>, \u043c\u044b \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0443\u0437\u0435\u043b. \u0415\u0441\u043b\u0438 <code>fiber.action<\/code> \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>UPDATE<\/code>, \u043c\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0443\u0437\u0435\u043b \u043d\u043e\u0432\u044b\u043c\u0438 \u043f\u0440\u043e\u043f\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function updateNode(node, prevProps, nextProps) {  \/\/ TODO }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>updateNode<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const isProperty = key => key !== \"children\" const wasAdded = (prev, next) => key =>  prev[key] !== next[key] const wasRemoved = (prev, next) => key => !(key in next)  function updateNode(node, prevProps, nextProps) {  \/\/ \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0441\u0442\u0430\u0440\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430  Object.keys(prevProps)    .filter(isProperty)    .filter(wasRemoved(prevProps, nextProps))    .forEach(key => {      dom[key] = \"\"    }) \u200b  \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0435 \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u0432\u0448\u0438\u0435\u0441\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430  Object.keys(nextProps)    .filter(isProperty)    .filter(wasAdded(prevProps, nextProps))    .forEach(key => {      dom[key] = nextProps[key]    }) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u043f\u044b \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u0432\u043e\u043b\u043e\u043a\u043e\u043d, \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u043e\u043f\u044b \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0435 \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u0432\u0448\u0438\u0435\u0441\u044f \u043f\u0440\u043e\u043f\u044b.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const isEvent = key => key.startsWith(\"on\") const isProperty = key =>  key !== \"children\" &amp;&amp; !isEvent(key)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u043e\u0441\u043e\u0431\u044b\u0445 \u043f\u0440\u043e\u043f\u043e\u0432 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 (event listeners). \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u0435\u0441\u043b\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u043f\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 <code>on<\/code>, \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u043f \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">Object.keys(prevProps)  .filter(isEvent)  .filter(    key =>      !(key in nextProps) ||      wasAdded(prevProps, nextProps)(key)  )  .forEach(key => {    const eventType = key      .toLowerCase()      .substring(2) \/\/ onClick -> click     node.removeEventListener(      eventType,      prevProps[key]    )  })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f, \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">Object.keys(nextProps)  .filter(isEvent)  .filter(wasAdded(prevProps, nextProps))  .forEach(key => {    const eventType = key      .toLowerCase()      .substring(2)     node.addEventListener(      eventType,      nextProps[key]    )  })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438.<\/p>\n<p>  <\/p>\n<h2 id=\"funkcionalnye-komponenty-functional-components\">\u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b (Functional Components)<\/h2>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/** @jsx MyReact.createElement *\/ function App(props) {  return (    &lt;section id=\"welcome\">      &lt;h1 title=\"hello\" className=\"title\">Hello from {props.who}!&lt;\/h1>      &lt;p style=\"color: green;\">&lt;span>React&lt;\/span> from {props.what}&lt;\/p>    &lt;\/section>  ) } const element = &lt;App who=\"MyReact\" what=\"scratch\" \/> const container = document.getElementById(\"root\") MyReact.render(element, container)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 <code>const element = &lt;App who=\"MyReact\" what=\"scratch\" \/><\/code> \u0432 <code>JS<\/code>, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const element = MyReact.createElement(App, {  who: \"MyReact\",  what: \"scratch\" })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u043e\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432\u043e\u043b\u043e\u043a\u043d\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0443\u0437\u043b\u0430<\/li>\n<li>\u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"javascript\">function performUnitOfWork(fiber) {  \/\/ !  const isFunctionComponent =    fiber.type instanceof Function   if (isFunctionComponent) {    updateFunctionComponent(fiber)  } else {    updateHostComponent(fiber)  }   \/\/ ... } \u200b function updateFunctionComponent(fiber) {  \/\/ TODO } \u200b function updateHostComponent(fiber) {  if (!fiber.node) {    fiber.node = createDom(fiber)  }   reconcileChildren(fiber, fiber.props.children) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u0442\u0438\u043f \u0432\u043e\u043b\u043e\u043a\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>updateHostComponent<\/code> \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438 \u0440\u0430\u043d\u044c\u0448\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export function updateFunctionComponent(fiber) {  const children = [fiber.type(fiber.props)]  reconcileChildren(fiber, children) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0410 \u0432 <code>updateFunctionalComponent<\/code> \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>fiber.type<\/code> \u2014 \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>App<\/code>, \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 <code>section<\/code> \u0441 \u043f\u043e\u0442\u043e\u043c\u043a\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<p>\u041b\u043e\u0433\u0438\u043a\u0430 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043c\u043a\u043e\u0432 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0436\u043d\u0435\u0439, \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u0432 \u043d\u0435\u0439 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c.<\/p>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u043d\u0430\u0441 \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0432\u043e\u043b\u043e\u043a\u043d\u043e \u0431\u0435\u0437 \u0443\u0437\u043b\u043e\u0432, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c 2 \u0432\u0435\u0449\u0438 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>commitWork<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">let parentFiber = fiber.parent while (!parentFiber.node) {  parentFiber = parentFiber.parent } const parentNode = parentFiber.node<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u043f\u0440\u0435\u0434\u043a\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0443\u0437\u043b\u0430 \u043c\u044b \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c\u0441\u044f \u0432\u0432\u0435\u0440\u0445 \u043f\u043e <code>fiber tree<\/code> \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043c \u0432\u043e\u043b\u043e\u043a\u043d\u043e \u0441 \u0443\u0437\u043b\u043e\u043c.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">case 'REMOVE':  return commitRemove(fiber)  function commitRemove(fiber) {  if (fiber.node) {    return fiber.node.remove()  }  commitRemove(fiber.child) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0410 \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0443\u0437\u043b\u0430 \u043c\u044b \u0434\u0432\u0438\u0433\u0430\u0435\u043c\u0441\u044f \u0432\u043d\u0438\u0437, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d \u043f\u043e\u0442\u043e\u043c\u043a\u0430 \u0441 \u0443\u0437\u043b\u043e\u043c. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442\u0441\u044f <code>commitRemove<\/code>, \u043c\u044b \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c <code>commitWork<\/code> \u0434\u043b\u044f \u0441\u0442\u0430\u0440\u044b\u0445 \u0443\u0437\u043b\u043e\u0432.<\/p>\n<p>  <\/p>\n<h2 id=\"huki-hooks\">\u0425\u0443\u043a\u0438 (Hooks)<\/h2>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u044d\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/** @jsx MyReact.createElement *\/ function Counter() {  const [state, setState] = MyReact.useState(1)   return (    &lt;h1 onClick={() => setState(c => c + 1)}>      Count: { state }    &lt;\/h1>  ) } const container = document.getElementById(\"root\") MyReact.render(&lt;Counter \/>, container)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0443 \u043d\u0430\u0441 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430. \u041f\u0440\u0438 \u043a\u043b\u0438\u043a\u0435 \u043f\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 1.<\/p>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>, \u0447\u0442\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>MyReact.useState<\/code> \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 function useState(initialState) {  \/\/ TODO }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>Counter<\/code>, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>useState<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ ! let workingFiber = null let hookIndex = null \u200b function updateFunctionComponent(fiber) {  \/\/ !  workingFiber = fiber  hookIndex = 0  workingFiber.hooks = []  \/\/ end !  const children = [fiber.type(fiber.props)]  reconcileChildren(fiber, children) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0445\u0443\u043a\u0430\u0445.<\/p>\n<p>  <\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u0432\u043e\u043b\u043e\u043a\u043d\u043e (<code>workingFiber<\/code>).<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 <code>hooks<\/code> \u0432 \u0432\u043e\u043b\u043e\u043a\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>useState<\/code> \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u0432 \u043e\u0434\u043d\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0438\u043d\u0434\u0435\u043a\u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0445\u0443\u043a\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function useState(initialState) {  const oldHook =    workingFiber.alternate &amp;&amp;    workingFiber.alternate.hooks &amp;&amp;    workingFiber.alternate.hooks[hookIndex]   const hook = {    state: oldHook ? oldHook.state : initialState,  } \u200b  workingFiber.hooks.push(hook)  hookIndex++   return [hook.state] }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 <code>useState<\/code> \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043b\u0438 \u0443 \u043d\u0430\u0441 \u0441\u0442\u0430\u0440\u044b\u0439 \u0445\u0443\u043a. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0437\u0430\u0433\u043b\u044f\u0434\u044b\u0432\u0430\u0435\u043c \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>alternate<\/code> \u0432\u043e\u043b\u043e\u043a\u043d\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0438\u043d\u0434\u0435\u043a\u0441 \u0445\u0443\u043a\u0430.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0442\u0430\u0440\u044b\u0439 \u0445\u0443\u043a \u0435\u0441\u0442\u044c, \u043c\u044b \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 \u043d\u043e\u0432\u044b\u0439 \u0445\u0443\u043a, \u0438\u043d\u0430\u0447\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c (\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u043c).<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0445\u0443\u043a \u0432 \u0432\u043e\u043b\u043e\u043a\u043d\u043e, \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u043d\u0430 1 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const hook = {    state: oldHook ? oldHook.state : initialState,    \/\/ !    queue: [],  } \u200b \/\/ ! const setState = action => {  hook.queue.push(action)   workingRoot = {    node: currentRoot.node,    props: currentRoot.props,    alternate: currentRoot,  }   nextUnitOfWork = workingRoot  nodesToRemove = [] } \u200b workingFiber.hooks.push(hook) hookIndex++  \/\/ ! return [hook.state, setState]<\/code><\/pre>\n<p>  <\/p>\n<p><code>useState<\/code> \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>setState<\/code>, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e (\u0432 <code>Counter<\/code> \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u2014 \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u043d\u0430 1).<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u044d\u0442\u0443 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c (<code>queue<\/code>) \u0445\u0443\u043a\u0430.<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>render<\/code>: \u043d\u043e\u0432\u044b\u0439 <code>workingRoot<\/code> \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u043d\u043e\u0432\u043e\u0439 \u0441\u0442\u0430\u0434\u0438\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const hook = {  state: oldHook ? oldHook.state : initial,  queue: [], } \u200b \/\/ ! const actions = oldHook ? oldHook.queue : [] actions.forEach(action => {  hook.state = action(hook.state) })<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u041c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0445\u0443\u043a\u0430 \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0438\u0445 \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u043a \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e \u0445\u0443\u043a\u0430. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u043d\u0430 \u044d\u0442\u043e\u043c \u043c\u044b \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f. \u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b \u0437\u043d\u0430\u0435\u0442\u0435, \u0441 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 <code>React<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u043f\u0440\u0435\u0436\u0434\u0435, \u0447\u0435\u043c \u043c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043c, \u0432\u043d\u0435\u0441\u0435\u043c \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u043b\u043a\u0438\u0445 \u043f\u0440\u0430\u0432\u043e\u043a.<\/p>\n<p>  <\/p>\n<ul>\n<li><code>initialState<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439:<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ useState const hook = {  state: oldHook    ? oldHook.state    \/\/ !    : initialState instanceof Function    ? initialState()    : initialState,  queue: [] }<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li><code>action<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u043c:<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ useState actions.forEach((action) => {  \/\/ !  hook.state = action instanceof Function ? action(hook.state) : action })<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li>\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u043f\u0440\u043e\u043f\u0430 <code>style<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442:<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ updateNode Object.keys(nextProps)  .filter(isProperty)  .filter(wasAdded(prevProps, nextProps))  .forEach((key) => {    \/\/ !    if (key === 'style' &amp;&amp; typeof nextProps[key] === 'object') {      Object.assign(node.style, nextProps[key])    } else {      node[key] = nextProps[key]    }  })<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li><code>children<\/code> \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432:<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ createElement children: children  .flat()  .map((child) =>    typeof child === 'object' ? child : createTextElement(child)  )<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"zapusk-proekta-s-pomoschyu-snowpack\">\u0417\u0430\u043f\u0443\u0441\u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>Snowpack<\/code><\/h2>\n<p>  <\/p>\n<p>\u0412\u0435\u0441\u044c \u043a\u043e\u0434 <code>MyReact<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435. \u042d\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e. \u041d\u043e \u0435\u0441\u043b\u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u043a\u043e\u0434 \u043d\u0430 \u043c\u043e\u0434\u0443\u043b\u0438, \u0442\u043e \u043d\u0430\u0447\u043d\u0443\u0442\u0441\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u0443\u044e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f <code>import<\/code> \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043c\u043e\u0434\u0443\u043b\u044f\u0445. \u0417\u0430\u0442\u0435\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u0447\u043d\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c <code>Babel<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u2014 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u043c\u0443 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u043b\u0430\u0433\u0438\u043d. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d \u043a <code>Babel<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u043b\u044c\u043a\u043e <code>babel.config.json<\/code> \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f. \u0417\u0434\u0435\u0441\u044c \u043d\u0443\u0436\u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430 (\u0431\u0430\u043d\u0434\u043b\u0435\u0440\u0430).<\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0440\u0435\u0447\u044c \u0437\u0430\u0445\u043e\u0434\u0438\u0442 \u043e \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430\u0445, \u044f, \u043e\u0431\u044b\u0447\u043d\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e <a href=\"https:\/\/webpack.js.org\/\"><code>Webpack<\/code><\/a>. \u041d\u043e \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u043d\u0430 \u0425\u0430\u0431\u0440\u0435 \u0432\u044b\u0448\u043b\u043e 2 \u0445\u043e\u0440\u043e\u0448\u0438\u0435 \u0441\u0442\u0430\u0442\u044c\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u044c <code>snowpack<\/code> \u0434\u0435\u043b\u0438\u0442\u0441\u044f \u0441\u0432\u043e\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0440\u0435\u0448\u0438\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 &#171;\u0441\u0431\u043e\u0440\u0449\u0438\u043a \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u043e\u0432&#187;.<\/p>\n<p>  <\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/yf\/n-\/vu\/yfn-vu2k1i_aepnbvr6yvhvtfqm.png\" data-src=\"https:\/\/habrastorage.org\/webt\/yf\/n-\/vu\/yfn-vu2k1i_aepnbvr6yvhvtfqm.png\"\/>  <\/p>\n<p>  \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442, \u043d\u0430\u0445\u043e\u0434\u044f\u0441\u044c \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">yarn init -yp<\/code><\/pre>\n<p>  <\/p>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c <code>snowpack<\/code>, 2 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0438 \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0434\u043b\u044f <code>babel<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">yarn add -D snowpack @snowpack\/plugin-babel @snowpack\/plugin-sass @babel\/preset-react<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c <code>snowpack<\/code> (<code>snowpack.config.json<\/code>):<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">{  \"plugins\": [    \"@snowpack\/plugin-babel\",    \"@snowpack\/plugin-sass\"  ] }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c <code>babel<\/code> (<code>babel.config.json<\/code>):<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">{  \"presets\": [    \"@babel\/preset-react\"  ] }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 <code>snowpack<\/code> \u0432 <code>package.json<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\"scripts\": {  \"start\": \"snowpack dev\" }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">yarn start<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0440\u0430\u0441\u043e\u0442\u0430:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/gp\/5l\/id\/gp5lidri_i8c94x05m2fsejuyqq.png\" data-src=\"https:\/\/habrastorage.org\/webt\/gp\/5l\/id\/gp5lidri_i8c94x05m2fsejuyqq.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<h2 id=\"zaklyuchenie\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p>\u0418\u0442\u0430\u043a, \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0441 \u0432\u0430\u043c\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043c\u0438\u043d\u0438-\u0432\u0435\u0440\u0441\u0438\u044e <code>React<\/code>. \u041e\u043d\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043d\u0430\u0438\u0432\u043d\u0443\u044e \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e <code>\u22480.1%<\/code> \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 <code>React<\/code>. \u041d\u043e, \u043a\u0430\u043a \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f, \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u2014 \u043d\u0430\u0447\u0430\u0442\u044c \ud83d\ude09<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u043e\u043c\u0443, \u043a\u0430\u043a \u0438 \u043c\u043d\u0435, \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u0430\u043b\u043e:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/facebook\/react\/tree\/main\/packages\/react\"><code>React<\/code><\/a> \u2014 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 <code>React<\/code><\/li>\n<li><a href=\"https:\/\/github.com\/DAB0mB\/jsx-runtime\"><code>JSX Runtime<\/code><\/a> \u2014 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0438\u043d\u0433 <code>JSX<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/JavaScript\/Reference\/Template_literals\"><code>tagged template literals<\/code><\/a><\/li>\n<li><a href=\"https:\/\/github.com\/yisar\/fre\"><code>Fre<\/code><\/a> \u2014 \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0435 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u0435, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435, \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043b\u044e\u0447\u0435\u0439<\/li>\n<li><a href=\"https:\/\/github.com\/davidbarone\/didact\"><code>@dbarone\/didact<\/code><\/a> \u2014 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u0445\u0443\u043a\u043e\u0432 <code>useEffect<\/code>, <code>useMemo<\/code> \u0438 <code>useCallback<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c \u0432\u0430\u043c \u0431\u044b\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0438 \u0432\u044b \u043d\u0435 \u0436\u0430\u043b\u0435\u0435\u0442\u0435 \u043f\u043e\u0442\u0440\u0430\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<p>  <\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0438 \u0445\u043e\u0440\u043e\u0448\u0435\u0433\u043e \u0434\u043d\u044f!<\/p>\n<p>  <\/p>\n<hr\/>\n<p>  <\/p>\n<blockquote><p><a href=\"https:\/\/t.me\/timewebru\"><b>\u041d\u043e\u0432\u043e\u0441\u0442\u0438, \u043e\u0431\u0437\u043e\u0440\u044b \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432 \u0438 \u043a\u043e\u043d\u043a\u0443\u0440\u0441\u044b \u043e\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b Timeweb.Cloud \u2014 \u0432 \u043d\u0430\u0448\u0435\u043c Telegram-\u043a\u0430\u043d\u0430\u043b\u0435<\/b><\/a> \u21a9<\/p><\/blockquote>\n<p><a href=\"https:\/\/timeweb.cloud\/?i=106909\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/b5\/pj\/of\/b5pjofdoxth14ro-rjsrn7sbmiy.png\" data-src=\"https:\/\/habrastorage.org\/webt\/b5\/pj\/of\/b5pjofdoxth14ro-rjsrn7sbmiy.png\"\/><\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/586972\/\"> https:\/\/habr.com\/ru\/articles\/586972\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/jc\/hw\/st\/jchwst6a3nwlxlscnmuw5tdhmry.png\" data-src=\"https:\/\/habrastorage.org\/webt\/jc\/hw\/st\/jchwst6a3nwlxlscnmuw5tdhmry.png\"\/>  <\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0442, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c, \u0441 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f <code>React<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442? \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043c\u0438\u043d\u0438-\u0432\u0435\u0440\u0441\u0438\u044e <code>React<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import '..\/style.scss' import MyReact from '.\/my-react'  const buttonStyles = {  border: 'none',  outline: 'none',  padding: '0.3rem 0.5rem',  marginLeft: '0.5rem',  backgroundImage: 'linear-gradient(yellow, orange)',  borderRadius: '2px',  boxShadow: '0 1px 2px rgba(0, 0, 0, 0.2)',  cursor: 'pointer' }  \/** @jsx MyReact.createElement *\/ function Counter() {  const [value, setValue] = MyReact.useState(1)  const [count, setCount] = MyReact.useState(1)   return (    &lt;section>      &lt;h1 className='title'>Hello from MyReact!&lt;\/h1>      &lt;div className='box'>        &lt;input          style='width: 80px; padding: 0.15rem 0.5rem;'          type='number'          value={value}          onInput={(e) => {            setValue(Number(e.target.value))          }}        \/>        &lt;button          style={buttonStyles}          onClick={() => {            setCount((count) => count + value)          }}        >          Increment        &lt;\/button>      &lt;\/div>      &lt;h2 className='subtitle'>        Count: &lt;span className='count-value'>{count}&lt;\/span>      &lt;\/h2>      &lt;ul className='list'>        {['React', 'from', 'scratch'].map((item) => (          &lt;li>{item}&lt;\/li>        ))}      &lt;\/ul>    &lt;\/section>  ) }  MyReact.render(&lt;Counter \/>, document.getElementById('app'))<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0432\u044b \u043c\u043e\u0433\u043b\u0438 \u0434\u043e\u0433\u0430\u0434\u0430\u0442\u044c\u0441\u044f, \u043d\u0430\u0448\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f <code>MyReact<\/code>.<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/harryheman\/Blog-Posts\/tree\/master\/react-clone\">\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0421\u043a\u0440\u0438\u043d\u0448\u043e\u0442:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/ba\/bq\/ue\/babque1vl1xr_ib8fsbn4275fzs.png\" data-src=\"https:\/\/habrastorage.org\/webt\/ba\/bq\/ue\/babque1vl1xr_ib8fsbn4275fzs.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0430:<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<div class=\"oembed\">\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/618136d94615593b75e246da\" data-style=\"\" id=\"618136d94615593b75e246da\" width=\"\"><\/div>\n<\/div>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b <a href=\"https:\/\/github.com\/facebook\/react\/tree\/main\/packages\/react\"><code>\u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 React<\/code><\/a>. \u0412\u043c\u0435\u0441\u0442\u0435 \u0441 \u0442\u0435\u043c, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0437\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 2 \u0433\u043e\u0434\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 <code>React<\/code> \u043f\u0440\u0435\u0442\u0435\u0440\u043f\u0435\u043b \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0449\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u044b \u0432 \u043d\u0435\u043c \u043a\u0430\u043a <code>legacy<\/code>. \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u044d\u0442\u043e, \u043e\u0431\u0449\u0438\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b \u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0435\u0436\u043d\u0438\u043c\u0438.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-413466","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/413466","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=413466"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/413466\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=413466"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=413466"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=413466"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}