{"id":330203,"date":"2022-02-28T21:00:20","date_gmt":"2022-02-28T21:00:20","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=330203"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=330203","title":{"rendered":"<span>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e React \u0441 \u043d\u0443\u043b\u044f<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u0414\u0435\u043c\u0438\u0441\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f React \u043f\u0443\u0442\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 DOM, \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438 \u0445\u0443\u043a\u0438 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430  <\/h2>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2cd\/123\/3b7\/2cd1233b7a31db6d0f7cd84af8054dc6.png\" width=\"780\" height=\"439\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2cd\/123\/3b7\/2cd1233b7a31db6d0f7cd84af8054dc6.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u0438\u0434\u043d\u044b \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0415\u0441\u043b\u0438 \u0440\u0430\u043d\u044c\u0448\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0430 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0438\u0441\u044c \u043b\u0438\u0448\u044c \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438, \u0442\u043e \u0432 \u043d\u0430\u0448\u0438 \u0434\u043d\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0438\u0437 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0425\u043e\u0442\u044f \u043c\u043d\u043e\u0433\u0438\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442 \u0442\u0430\u043a\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043a\u0430\u043a React \u0438\u043b\u0438 Vue, \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0438\u0445 \u0442\u043e\u0447\u043d\u043e\u0439 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0448\u0438\u0440\u043e\u043a\u043e \u0438\u0437\u0443\u0447\u0435\u043d\u043e. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0438 \u0440\u0430\u0437\u044a\u044f\u0441\u043d\u044e, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c.<\/p>\n<p>\u041d\u043e \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043c\u044b \u043d\u0430\u0447\u043d\u0435\u043c, \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435. \u0425\u043e\u0442\u044f \u043d\u0430\u0448\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0432\u043f\u043e\u043b\u043d\u0435 \u0440\u0430\u0431\u043e\u0447\u0430\u044f (\u0441\u043c. \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 \u043a\u043e\u043d\u0446\u0435), \u044d\u0442\u043e, \u043f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e, \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u0430 \u043d\u0435 \u043b\u0435\u0433\u043a\u043e\u0432\u0435\u0441\u043d\u0430\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 React. \u0412\u0435\u0441\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0430 <a href=\"https:\/\/github.com\/WimJongeneel\/ts-reactive-rendering\"><u>GitHub<\/u><\/a>.<\/p>\n<h3>1. \u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430<\/h3>\n<p>\u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u0432 \u043b\u044e\u0431\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 &#8212; \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u0420\u0430\u0431\u043e\u0442\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u043c &#171;\u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e\u043c&#187;. \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e (&#171;state&#187;) \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0435\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432 DOM. \u0417\u0434\u0435\u0441\u044c \u0443\u0436\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f, \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0435 \u0432\u0430\u043c \u043f\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e react-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 : <code>this.state<\/code>, <code>this.setState<\/code> \u0438 <code>render<\/code>.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3f0\/a43\/ede\/3f0a43edea89d4369359f93a8ee165ce.png\" width=\"494\" height=\"563\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3f0\/a43\/ede\/3f0a43edea89d4369359f93a8ee165ce.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u041a\u0430\u0436\u0434\u0430\u044f \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0446\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u043e\u0435 state (\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435), \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u043d\u043e\u0432\u0443\u044e VDOM, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0449\u0443\u044e HTML \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<p>\u041a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u043c \u0432 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u043c\u044b\u0448\u043b\u0435\u043d\u0438\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 DOM \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0432\u0435\u0449\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u0435 jQuery). \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u043e\u0434\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0438 \u043e\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u0425\u043e\u0442\u044f \u0438\u0434\u0435\u044f &#171;\u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430&#187; \u0432\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u0430 (\u043c\u0435\u043d\u044c\u0448\u0435 \u043a\u043e\u0434\u0430, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 DOM \u0438 \u0442.\u0434.), \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0434\u0440\u0443\u0433\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430: \u0435\u0441\u043b\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c \u0432\u0441\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 DOM \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438, \u044d\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043d\u0435\u0443\u0434\u043e\u0431\u0441\u0442\u0432. \u041f\u043e\u043c\u0438\u043c\u043e \u043f\u043e\u0442\u0435\u0440\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u044d\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043a \u0443\u0442\u0440\u0430\u0442\u0435 \u0444\u043e\u043a\u0443\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c, \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u043c \u0441\u043a\u0430\u0447\u043a\u0430\u043c \u043f\u0440\u0438 \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0435 \u0438 \u0442.\u0434.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u044d\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e DOM \u0441 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f (diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c) \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u0442\u0435\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0430 \u043a \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 DOM. \u0412\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 DOM \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0432\u0441\u0435, \u0447\u0442\u043e \u0437\u0430\u0445\u043e\u0442\u0438\u043c, \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 JavaScript \u0441 \u043f\u0440\u0438\u0447\u0443\u0434\u043b\u0438\u0432\u044b\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c, \u0430 \u043d\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u0430\u044f DOM. \u0418 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u043c\u043d\u043e\u0433\u043e diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u043c\u043e\u0436\u043d\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u0443\u044e DOM \u0432\u043d\u0435\u0441\u0435\u043d\u043e \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0442\u0430\u043a\u0443\u044e \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e DOM \u0434\u0430\u0436\u0435 \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0439, \u0447\u0435\u043c \u043b\u044e\u0431\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f DOM, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0442\u0430\u043a\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 DOM. \u041e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0449\u0435 \u0442\u043e\u0439, \u0447\u0442\u043e \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435 React, \u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0438, \u0447\u0442\u043e \u0432\u0430\u0436\u043d\u043e, \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 DOM. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0438 \u043f\u0440\u043e\u043f\u0441\u0430\u043c\u0438, \u0438 \u0442\u043e, \u043a\u0430\u043a \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f \u0442\u0430\u043a\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043e\u0431\u044b\u0433\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 DOM. \u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<h3>2. \u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f DOM<\/h3>\n<p>\u041f\u043e \u0441\u0432\u043e\u0435\u0439 \u0441\u0443\u0442\u0438 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f DOM \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0434\u0430\u043d\u043d\u044b\u0445: \u0434\u0435\u0440\u0435\u0432\u0430 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 HTML \u0438 diff-\u0434\u0435\u0440\u0435\u0432\u0430. \u0414\u0435\u0440\u0435\u0432\u043e HTML \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 HTML \u0432 JavaScript-\u043e\u0431\u044a\u0435\u043a\u0442\u0435 . \u042d\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f \u043c\u0435\u0442\u043e\u0434\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u0442\u043e, \u0441 \u0447\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443. Diff-\u0434\u0435\u0440\u0435\u0432\u043e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442, \u043a\u0430\u043a\u0438\u0435 \u0448\u0430\u0433\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 HTML \u0438\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ba2\/7bd\/ba4\/ba27bdba49ffe8b6a147afdfc377cb27.png\" alt=\"\u0421\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 VDOM-\u0434\u0435\u0440\u0435\u0432\u044c\u044f\u043c\u0438, diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c \u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u043e\u0439 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f (diff)\u00a0\" title=\"\u0421\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 VDOM-\u0434\u0435\u0440\u0435\u0432\u044c\u044f\u043c\u0438, diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c \u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u043e\u0439 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f (diff)\u00a0\" width=\"551\" height=\"198\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ba2\/7bd\/ba4\/ba27bdba49ffe8b6a147afdfc377cb27.png\"\/><figcaption>\u0421\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 VDOM-\u0434\u0435\u0440\u0435\u0432\u044c\u044f\u043c\u0438, diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c \u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u043e\u0439 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f (diff)\u00a0<\/figcaption><\/figure>\n<h4>2.1 \u0414\u0435\u0440\u0435\u0432\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 HTML<\/h4>\n<p>\u042d\u0442\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 DOM. \u041f\u043e\u043a\u0430 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0443\u0437\u043b\u044b. \u041f\u043e\u0437\u0436\u0435 \u044d\u0442\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u0441\u044f, \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u0434\u0435\u0440\u0435\u0432\u0430. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043e \u043d\u0438\u0436\u0435. \u0421\u0432\u043e\u0439\u0441\u0442\u0432\u043e key \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0442\u0435, \u043a\u0442\u043e \u0437\u043d\u0430\u043a\u043e\u043c \u0441 React, \u0443\u0436\u0435 \u043f\u043e\u043d\u044f\u043b\u0438 \u044d\u0442\u043e.<\/p>\n<pre><code class=\"javascript\">export type VDOMAttributes = { [_: string]: string | number | boolean | Function }  export interface VDOMElement {   kind: 'element'   tagname: string   childeren?: VDomNode[]   props?: VDOMAttributes   key: string | number }  export interface VDOMText {   kind: 'text',   value: string   key: string | number }  export type VDomNode =  | VDOMText | VDOMElement<\/code><\/pre>\n<p><em>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 VDOM.<\/em><\/p>\n<p>\u041d\u0430\u0448\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c JSX, \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u0445\u0435\u043b\u043f\u0435\u0440\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 VDOM \u0443\u0434\u043e\u0431\u043d\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c. \u041e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043d\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u043e\u0432 React.createElement, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0432\u044b, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0438\u0441\u044c \u0432 \u0441\u0432\u043e\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u0430\u0445 JavaScript.<\/p>\n<pre><code class=\"javascript\">export const createElement = (tagname: string, props: VDOMAttributes &amp; { key: string }, ...childeren: VDomNode[]): VDOMElement => {   const key = props.key   delete props.key   return ({ kind: 'element',     tagname, props,     childeren, key   }) }  export const createText = (value: string | number | boolean, key: string = '') : VDOMText => ({   key, kind: 'text', value: value.toString() })<\/code><\/pre>\n<p><em>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 VDOM.<\/em><\/p>\n<h4>2.2 \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 diff<\/h4>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f (diffing), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043e\u0434\u043d\u0438\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c, \u0430 \u0437\u0430\u0442\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u043c \u0435\u0433\u043e \u0437\u0430 \u0441\u0447\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0438\u043f \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f &#8212; \u044d\u0442\u043e \u043c\u0443\u0442\u0430\u0446\u0438\u044f DOM, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0430 \u0441 \u043e\u0434\u043d\u0438\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c HTML. \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f update \u0438 replace. \u0422\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c skip, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u043d\u0430 \u043e\u0442\u043a\u0430\u0437 \u043e\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439.<\/p>\n<pre><code>type AttributesUpdater = {   set: VDOMAttributes   remove: string[] }  interface UpdateOperation {   kind: 'update',   attributes: AttributesUpdater,   childeren: ChildUpdater[] }  interface ReplaceOperation {   kind: 'replace',   newNode: VDomNode }  interface SkipOperation {    kind: 'skip'  }  export type VDomNodeUpdater =    | UpdateOperation   | ReplaceOperation   | SkipOperation<\/code><\/pre>\n<p><em>\u0422\u0438\u043f\u044b \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0445 \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443.<\/em><\/p>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f update \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 diff-\u0434\u0435\u0440\u0435\u0432\u043e \u0438 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0448\u0430\u0433\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 setState. \u0422\u0430\u043a\u0436\u0435 \u0437\u0434\u0435\u0441\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u043a \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u041f\u043e\u043c\u0438\u043c\u043e \u0442\u0435\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0443\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438, \u043e\u043d\u0438 \u0442\u0430\u043a\u0436\u0435 \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442 insert \u0438 remove:<\/p>\n<pre><code>interface RemoveOperation {   kind: 'remove' }  interface InsertOperation {   kind: 'insert',    node: VDomNode }  export type ChildUpdater =   | UpdateOperation   | ReplaceOperation   | RemoveOperation   | SkipOperation   | InsertOperation<\/code><\/pre>\n<p><em>\u0422\u0438\u043f\u044b \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u044b \u043a \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c<\/em>.<\/p>\n<h3>3. \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 diff&#8217;\u043e\u0432<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e DOM \u0438 diff, \u0434\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u043e, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 VDOM \u0441\u0442\u043e\u044f\u0449\u0438\u043c \u0443\u0441\u0438\u043b\u0438\u0439: diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c . \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u0448\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0435, \u044d\u0442\u043e \u0432\u0430\u0436\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u0440\u0435\u0447\u044c \u043e \u043f\u043b\u0430\u0432\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0439 \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0438\u0441\u0442\u044b\u0439 diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043e\u043f\u044b\u0442 \u043b\u044e\u0431\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0442\u043e\u0433\u043e, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u044b \u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<p>\u041c\u044b \u0440\u0430\u0437\u043b\u043e\u0436\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043d\u0430 \u0434\u0432\u0435 \u0447\u0430\u0441\u0442\u0438: \u0441\u043d\u0430\u0447\u0430\u043b\u0430 diffing \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u043f\u043e\u0442\u043e\u043c diffing \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 (\u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445) \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u043b\u043e\u0441\u044c \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0439 \u0442\u0438\u043f\u043e\u0432.<\/p>\n<h4>3.1 \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 diff&#8217;\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430<\/h4>\n<p>\u041f\u0440\u0438 diffing&#8217;\u0435 VDOM \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0434\u0435\u043b\u043e \u0441 \u0434\u0432\u0443\u043c\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0432\u0435\u0449\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f: \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0443\u0437\u043b\u044b \u0438 HTML-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b. \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u0443\u0437\u043b\u043e\u0432, \u0442.\u043a. \u043e\u043d\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b. \u0415\u0441\u043b\u0438 \u043e\u0431\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u043c\u0438 \u0443\u0437\u043b\u0430\u043c\u0438 \u0438 \u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c, \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e skip. \u0412 \u043b\u044e\u0431\u043e\u043c \u0434\u0440\u0443\u0433\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u0433\u0434\u0430 \u0435\u0441\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0443\u0437\u0435\u043b, \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043d\u043e\u0432\u044b\u043c:<\/p>\n<pre><code class=\"javascript\">export const createDiff = (oldNode: VDomNode, newNode: VDomNode): VDomNodeUpdater => {   \/\/ skip over text nodes with the same text   if (oldNode.kind == 'text' &amp;&amp; newNode.kind == 'text' &amp;&amp; oldNode.value == newNode.value) {     return skip()   }    \/\/ If a textnode is updated we need to replace it completly   if (oldNode.kind == 'text' || newNode.kind == 'text') {       return replace(newNode)   }   \/\/ rest of the diffing }<\/code><\/pre>\n<p><em>Diffing \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u0443\u0437\u043b\u043e\u0432.<\/em><\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u043c\u044b \u0443\u0431\u0435\u0434\u0438\u043b\u0438\u0441\u044c, \u0447\u0442\u043e \u043e\u0431\u0430 \u0443\u0437\u043b\u0430 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438. \u041d\u043e \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u043e\u0434\u0438\u043d \u0441\u043b\u0443\u0447\u0430\u0439, \u0433\u0434\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0443\u0437\u0435\u043b: \u043a\u043e\u0433\u0434\u0430 tagname \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f. \u042d\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435,\u0447\u0442\u043e \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043d\u0430\u0448\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e:<\/p>\n<pre><code class=\"javascript\">export const createDiff = (oldNode: VDomNode, newNode: VDomNode): VDomNodeUpdater => {   \/\/ diff text nodes      \/\/ If the tagname of a node is changed we have to replace it completly   if (oldNode.tagname != oldNode.tagname) {     return replace(newNode)   }    \/\/ diff elements }<\/code><\/pre>\n<p><em>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0435 <\/em><code>tagname<\/code><em> \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0432\u0435\u0441\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d \u0437\u0430\u043d\u043e\u0432\u043e.<\/em><\/p>\n<p>\u0414\u0432\u0430 \u0438\u043c\u0435\u044e\u0449\u0438\u0445\u0441\u044f \u0443 \u043d\u0430\u0441 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438\u043c\u0435\u044e\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0442\u0438\u043f \u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u044b \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0435 \u0431\u0435\u0437 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c: \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u044b; \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u044b; \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432:<\/p>\n<pre><code class=\"javascript\">export const createDiff = (oldNode: VDomNode, newNode: VDomNode): VDomNodeUpdater => {   \/\/ diff text nodes and replaced elements      \/\/ get the updated and replaced attributes   const attUpdater: AttributesUpdater = {     remove: Object.keys(oldNode.props || {})       .filter(att => Object.keys(newNode).indexOf(att) == -1),     set: Object.keys(newNode.props || {})       .filter(att => oldNode.props[att] != newNode.props[att])       .reduce((upd, att) => ({ ...upd, [att]: newNode.props[att] }), {})   }    const childsUpdater: ChildUpdater[] = childsDiff((oldNode.childeren || []), (newNode.childeren || []))    return update(attUpdater, childsUpdater) }<\/code><\/pre>\n<p><em>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u0441\u0435\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f.<\/em><\/p>\n<p>\u041c\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0438 \u043b\u043e\u0433\u0438\u043a\u0443 diffing&#8217;\u0430 \u0434\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u041a\u0430\u043a \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0434\u0435\u0440\u0435\u0432\u043e\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 HTML, \u043f\u043e\u0437\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 diffing&#8217;\u0430 \u0438 \u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043b\u043e\u0433\u0438\u043a\u0435 diffing&#8217;\u0430 \u0434\u043b\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<h4>3.2 \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 diff \u0434\u043b\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u044c\u044e diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f diffing \u0434\u043b\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u042d\u0442\u043e, \u0441\u0430\u043c\u0430\u044f \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c VDOM, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 \u0441 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438. \u041c\u043e\u0436\u043d\u043e \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u043d\u0430\u0447\u0430\u043b\u043e, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0443 \u0438\u043b\u0438 \u0432 \u043a\u043e\u043d\u0435\u0446; \u0443\u0434\u0430\u043b\u0438\u0442\u044c, \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b. \u0417\u0434\u0435\u0441\u044c \u0432 \u0438\u0433\u0440\u0443 \u0432\u0441\u0442\u0443\u043f\u0430\u0435\u0442 key \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430: \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0436\u0438\u043c, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043a\u043b\u044e\u0447\u0438 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442, \u0442\u043e \u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b (\u043d\u043e \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b). \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043b\u044e\u0447\u0435\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c, \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0434\u0435\u0440\u0435\u0432\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u0440\u0435\u0442\u044c\u0435\u043c\u0443 \u0432 \u043d\u043e\u0432\u043e\u043c \u0434\u0435\u0440\u0435\u0432\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u043e\u0441\u044c \u0434\u0432\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432\u043f\u0435\u0440\u0435\u0434\u0438. \u0411\u0435\u0437 \u043a\u043b\u044e\u0447\u0435\u0439 \u044d\u0442\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/508\/3e7\/56c\/5083e756c3c855dc7363f6508c6f621a.png\" alt=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u0441 diff-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f\u043c\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 VDOM\" title=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u0441 diff-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f\u043c\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 VDOM\" width=\"587\" height=\"273\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/508\/3e7\/56c\/5083e756c3c855dc7363f6508c6f621a.png\"\/><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 \u0441 diff-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f\u043c\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 VDOM<\/figcaption><\/figure>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u0443\u044e \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e, \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0443\u044e \u043f\u0435\u0440\u0435\u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0438\u0432\u0430\u043d\u0438\u0435 \u043a\u043b\u044e\u0447\u0435\u0439 (\u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0435\u0440\u0435\u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c remove \u0438 insert \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043d\u0435 \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443). \u042d\u0442\u043e \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442 \u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430. \u041d\u0430\u0447\u043d\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0434\u0432\u0443\u0445 \u0441\u0442\u0435\u043a\u043e\u0432 \u0438\u0437 \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0445\u0441\u044f \u043d\u0435\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u043c\u0438 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430:<\/p>\n<pre><code class=\"javascript\">const childsDiff = (oldChilds: VDomNode[], newChilds: VDomNode[]): ChildUpdater[] => {   const remainingOldChilds: [string | number, VDomNode][] = oldChilds.map(c => [c.key, c])   const remainingNewChilds: [string | number, VDomNode][] = newChilds.map(c => [c.key, c])    const operations: ChildUpdater[] = []      return operations }<\/code><\/pre>\n<p><em>\u0411\u0430\u0437\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 childsDiff.<\/em><\/p>\n<p>\u0412 \u0441\u0442\u0440\u043e\u043a\u0435 6 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043b\u043e\u0433\u0438\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442 operations \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 \u0432 \u043d\u043e\u0432\u043e\u0435. \u042d\u0442\u043e\u0442 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0435\u043d \u043d\u0430 \u043f\u043e\u0438\u0441\u043a\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 (= \u043a\u043b\u044e\u0447\u0435\u0439), \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043a\u0430\u043a \u0432 \u0441\u0442\u0430\u0440\u043e\u0439, \u0442\u0430\u043a \u0438 \u0432 \u043d\u043e\u0432\u043e\u0439 VDOM. \u0414\u043b\u044f \u043d\u0438\u0445 \u0431\u0443\u0434\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f, \u0430 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u044b \u0438\u043b\u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b. \u041d\u0438\u0436\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0430 \u044d\u0442\u0430 \u0447\u0430\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0438. \u041f\u043e\u043a\u0430 \u0432 \u0441\u0442\u0435\u043a\u0430\u0445 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u043c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043d\u0438\u0445 update \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"javascript\">const childsDiff = (oldChilds: VDomNode[], newChilds: VDomNode[]): ChildUpdater[] => {   const remainingOldChilds: [string | number, VDomNode][] = oldChilds.map(c => [c.key, c])   const remainingNewChilds: [string | number, VDomNode][] = newChilds.map(c => [c.key, c])    const operations: ChildUpdater[] = []    \/\/ find the first element that got updated   let [ nextUpdateKey ] = remainingOldChilds.find(k => remainingNewChilds.map(k => k[0]).indexOf(k[0]) != -1) || [null]    while(nextUpdateKey) {           \/\/ process other children here          \/\/ create the update     operations.push(createDiff(remainingOldChilds.shift()[1], remainingNewChilds.shift()[1]))      \/\/ find the next update     ; [ nextUpdateKey ] = remainingOldChilds.find(k => remainingNewChilds.map(k => k[0]).indexOf(k[0]) != -1) || [null]   }      \/\/ process the remaining children here      return operations }<\/code><\/pre>\n<p>\u041f\u0440\u0438 diffing&#8217;\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u044b \u0437\u0430\u0431\u043e\u0442\u0438\u043c\u0441\u044f \u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043d\u043e\u0432\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445.\u00a0<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u0430\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e <code>nextUpdatedKey<\/code> \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u043c \u0438\u0437 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043a\u0430\u043a \u0432 <code>remainingOldChilds<\/code>, \u0442\u0430\u043a \u0438 \u0432 <code>remainingNewChilds<\/code>. \u041f\u0435\u0440\u0435\u0434 \u043d\u0438\u043c\u0438 \u0432 \u0441\u0442\u0435\u043a\u0430\u0445 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u044b \u0438\u043b\u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0438 \u043f\u043e\u0442\u043e\u043c\u0443 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0432 \u043e\u0431\u0435\u0438\u0445 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f\u0445. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0434\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u0442\u0430\u0440\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438 \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0435, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435.<\/p>\n<pre><code class=\"javascript\">\/\/ create stacks and the first update   while(nextUpdateKey) {      \/\/ first remove all old childs before the update     removeUntilkey(operations, remainingOldChilds, nextUpdateKey)          \/\/ then insert all new childs before the update     insertUntilKey(operations, remainingNewChilds, nextUpdateKey)      \/\/ generate update }<\/code><\/pre>\n<pre><code class=\"javascript\">const removeUntilkey = (operations: ChildUpdater[], elems: [string | number, VDomNode][], key: string | number) => {   while(elems[0] &amp;&amp; elems[0][0] != key) {     operations.push(remove())     elems.shift()   } }  const insertUntilKey = (operations: ChildUpdater[], elems: [string | number, VDomNode][], key: string | number) => {   while(elems[0] &amp;&amp; elems[0][0] != key) {     operations.push(insert(elems.shift()[1]))   } }<\/code><\/pre>\n<p>\u0421\u0442\u0430\u0440\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043d\u0430\u0434\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c, \u0430 \u043d\u043e\u0432\u044b\u0435 &#8212; \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0441\u0435\u0445 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0443\u0437\u043b\u043e\u0432 \u0432\u0441\u0435 \u0435\u0449\u0435 \u043c\u043e\u0433\u0443\u0442 \u043e\u0441\u0442\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b. \u042d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u043a\u043e\u0433\u0434\u0430 \u0432 \u043d\u0438\u0436\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0434\u0435\u0440\u0435\u0432\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u044f\u044e\u0442\u0441\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b. \u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043d\u0438\u0436\u0435:<\/p>\n<pre><code class=\"javascript\"> while(nextUpdateKey) {     \/\/ generate updates here   }    \/\/ remove all remaing old childs after the last update   removeUntilkey(operations, remainingOldChilds, undefined)    \/\/ insert all remaing new childs after the last update   insertUntilKey(operations, remainingNewChilds, undefined)    return operations }<\/code><\/pre>\n<p><em>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 <\/em><code>remove<\/code><em> \u0438 <\/em><code>insert<\/code><em> \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439.<\/em><\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 diffs \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0434\u0435\u0440\u0435\u0432\u044c\u0435\u0432 \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u044b\u0439 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 diff. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u0430\u0436\u0434\u0430\u044f \u043f\u0430\u0440\u0430 remove \u0438 insert \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u0434\u043d\u043e\u0439 replace. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e \u043a\u043b\u044e\u0447\u0430\u043c, \u0447\u0442\u043e \u0432\u0430\u0436\u043d\u043e \u0434\u043b\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c78\/31a\/03c\/c7831a03c5606ad9dbf8772169990d7d.png\" alt=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0435\u0440\u0435\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043a\u043b\u044e\u0447\u0435\u0439. B \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u0435\u043d. \u0415\u0441\u043b\u0438 B \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0442\u043e B \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u00a0\" title=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0435\u0440\u0435\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043a\u043b\u044e\u0447\u0435\u0439. B \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u0435\u043d. \u0415\u0441\u043b\u0438 B \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0442\u043e B \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u00a0\" width=\"727\" height=\"318\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c78\/31a\/03c\/c7831a03c5606ad9dbf8772169990d7d.png\"\/><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0435\u0440\u0435\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043a\u043b\u044e\u0447\u0435\u0439. B \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u0435\u043d. \u0415\u0441\u043b\u0438 B \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0442\u043e B \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u00a0<\/figcaption><\/figure>\n<h3>4. \u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 DOM<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0435\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u0430\u044f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f DOM, \u043f\u043e\u0440\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0435\u0435 \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0434\u0432\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438: \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0435\u0440\u0435\u0442 VDOM \u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442 \u0435\u0435 \u0432 DOM, \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 diff \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u0435\u0433\u043e \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u0432 DOM.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5c0\/185\/c3b\/5c0185c3babf8adf1c14d3c08c89c5eb.png\" alt=\"\u0421\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 diff, \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c HTML \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 apply\u00a0\" title=\"\u0421\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 diff, \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c HTML \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 apply\u00a0\" width=\"545\" height=\"206\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5c0\/185\/c3b\/5c0185c3babf8adf1c14d3c08c89c5eb.png\"\/><figcaption>\u0421\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 diff, \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c HTML \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 apply\u00a0<\/figcaption><\/figure>\n<h4>4.1 \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 DOM<\/h4>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 DOM, &#8212; \u043d\u0430\u0434\u043e \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043f\u0435\u0440\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f applyDiff \u0441\u0442\u0430\u043d\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 DOM \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c. \u041f\u043e \u0441\u0443\u0442\u0438, \u043e\u043d\u0430 \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u0432\u044b\u0437\u043e\u0432\u0443 document.createElement \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 \u0434\u0435\u0440\u0435\u0432\u0435:<\/p>\n<pre><code class=\"javascript\">const renderElement = (rootNode: VDomNode): HTMLElement | Text => {   if (rootNode.kind == 'text') {     return document.createTextNode(rootNode.value)   }    const elem = document.createElement(rootNode.tagname)    for (const att in (rootNode.props || {})) {     (elem as any)[att] = rootNode.props[att]   }    (rootNode.childeren || []).forEach(child =>     elem.appendChild(renderElement(child))   )    return elem }<\/code><\/pre>\n<p><em>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 VDOM \u0432 HTML-\u044d\u043b\u0435\u043c\u0435\u043d\u0442<\/em>.<\/p>\n<p>\u041c\u044b \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0432 React \u044d\u0442\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043d\u0435 \u0442\u0430\u043a. \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e setAttribute \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0438\u043d\u0442\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 DOM \u0438 VDOM. \u0417\u0434\u0435\u0441\u044c \u044f \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u043b \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u0435\u0435 \u0432 \u0440\u0430\u0437\u043c\u0435\u0440\u0430\u0445&#8230;<\/p>\n<h4>4.2 \u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 diff \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 HTML<\/h4>\n<p>\u0414\u0440\u0443\u0433\u0430\u044f \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 &#8212; \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 diff. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0431\u0435\u0440\u0435\u0442 HTMLElement \u0438 diff \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u0435\u0433\u043e \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443. \u0417\u0434\u0435\u0441\u044c \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u0442\u0435 \u0436\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u0440\u0430\u043d\u0435\u0435. \u0414\u043b\u044f \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0442\u0438 \u044f \u043e\u043f\u0443\u0441\u0442\u0438\u043b \u0432\u0441\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 TypeScript, \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u0447\u0442\u043e \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443, \u0430 \u043d\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u043c\u0443 \u0443\u0437\u043b\u0443.<\/p>\n<pre><code class=\"javascript\">export const applyUpdate = (elem: HTMLElement | Text, diff: VDomNodeUpdater): HTMLElement | Text => {   if (diff.kind == 'skip') return elem     if (diff.kind == 'replace') {     const newElem = renderElement(diff.newNode)     elem.replaceWith(newElem)     return newElem   }    if('wholeText' in elem) throw new Error('invalid update for Text node')    for (const att in diff.attributes.remove) {     elem.removeAttribute(att)   }    for (const att in diff.attributes.set) {     (elem as any)[att] = diff.attributes.set[att]   }    applyChildrenDiff(elem, diff.childeren)    return elem }<\/code><\/pre>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 diff \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438 VDOM \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 DOM.<\/em><\/p>\n<p>\u0412 <code>applyChildrenDiff<\/code> \u043c\u044b \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0438\u0445 \u043a \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0434\u0435\u0441\u044c \u0441\u0432\u044f\u0437\u0430\u043d\u0430 \u0441 offset, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u043a \u043a\u0430\u043a\u043e\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u0432 DOM \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f. \u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<pre><code class=\"javascript\">const applyChildrenDiff = (elem: HTMLElement, operations: ChildUpdater[]) => {   let offset = 0   for (let i = 0; i &lt; operations.length; i++) {     const childUpdater = operations[i]      if (childUpdater.kind == 'skip') continue      if (childUpdater.kind == 'insert') {       if (elem.childNodes[i + offset - 1]) elem.childNodes[i + offset - 1].after(renderElement(childUpdater.node))       else elem.appendChild(renderElement(childUpdater.node))       continue     }          const childElem = elem.childNodes[i + offset]      if (childUpdater.kind == 'remove') {       childElem.remove()       offset -= 1       continue     }      applyUpdate(childElem, childUpdater)   } }<\/code><\/pre>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043d\u0430\u0431\u043e\u0440\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043a \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c HTML-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430.<\/em><\/p>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 VDOM \u0438 \u0432\u0441\u0435\u0433\u043e, \u0447\u0442\u043e \u0441 \u043d\u0435\u0439 \u0441\u0432\u044f\u0437\u0430\u043d\u043e. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u044d\u0442\u0430\u043f\u043e\u043c \u043d\u0430\u0448\u0435\u0433\u043e \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0438\u0445 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<h3>5. \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0417\u043d\u0430\u043a\u043e\u043c\u044b\u0435 \u0441 React, \u0437\u043d\u0430\u044e\u0442 \u0447\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b &#8212; \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435. \u0425\u043e\u0442\u044f \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0430\u0436\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 &#8212; \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u044c\u044e. \u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c? \u042d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u0430 VDOM, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0441\u0432\u043e\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f. \u0422\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438\u043c\u0435\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 html-\u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 DOM, \u0433\u0434\u0435 \u043e\u043d \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d, \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 diffs \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u043f\u0440\u043e\u043f\u0441\u043e\u0432. \u0414\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044e, \u043e\u043d \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0438 diffing.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/56c\/4b7\/7a8\/56c4b77a8acba4c99b8a18e358c2e8fe.png\" alt=\"\u0425\u0443\u043a\u0438 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432\" title=\"\u0425\u0443\u043a\u0438 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432\" width=\"875\" height=\"229\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/56c\/4b7\/7a8\/56c4b77a8acba4c99b8a18e358c2e8fe.png\"\/><figcaption>\u0425\u0443\u043a\u0438 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432<\/figcaption><\/figure>\n<h4>5.1 \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430<\/h4>\n<p>\u041c\u044b \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u0440\u043e\u043f\u0441, \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438 VDOM. \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043d\u0430\u0431\u0440\u043e\u0441\u043e\u043a \u0442\u0430\u043a\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u043f\u043e\u043a\u0430\u0437\u0430\u043d \u043d\u0438\u0436\u0435. \u041c\u043d\u043e\u0433\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u043f\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c \u0442\u0438\u043f\u0430 React, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, props, state, setState, componentDidMount \u0438 render.<\/p>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u043c\u0435\u0442\u043e\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. setProps \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u043d\u043e\u0432\u044b\u0435 \u043f\u0440\u043e\u043f\u0441\u044b. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u043c\u0435\u0436\u0434\u0443 \u0435\u0433\u043e VDOM \u0438 \u043d\u043e\u0432\u043e\u0439 VDOM \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f. initProps \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0443\u044e VDOM, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c\u0441\u044f \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 DOM. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d notifyMounted, \u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d \u0432 DOM. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434 unmount, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0438\u0437 DOM.<\/p>\n<pre><code class=\"javascript\">export abstract class Component&lt;P, S> {          protected props: P     protected state: S          private currentRootNode: VDomNode     private mountedElement: HTMLElement | Text          protected setState(updater: (s:S) => S) { }          \/\/ called when the mounted element recieves new props     public setProps(props: P): VDomNodeUpdater { }          \/\/ called when mounting the element to generate the first VDOM state     public initProps(props: P): VDomNode { }          \/\/ this gets called when the component is mounted in the real DOM     public notifyMounted(elem: HTMLElement | Text) { }      \/\/ this gets called when the component will be unmounted in the real DOM     public unmount() { }          \/\/ hooks     public componentDidMount() {}     public componentWillRecieveProps(props: P, state: S): S { return state }     public componentDidUpdate() { }     public componentWillUnmount() { }          \/\/ the render function each component has to implement     public abstract render(): VDomNode }<\/code><\/pre>\n<p><em>\u041d\u0430\u0431\u0440\u043e\u0441\u043e\u043a \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 Component.<\/em><\/p>\n<p>\u0415\u0449\u0435 \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u043f\u0443\u0441\u0442\u044b\u0435 \u0445\u0443\u043a-\u043c\u0435\u0442\u043e\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u0438\u0445 \u043a \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u043d\u0430\u0448\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043f\u043e \u0445\u043e\u0434\u0443 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<h4>5.2 \u041c\u043e\u043d\u0442\u0430\u0436 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432<\/h4>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0448\u0430\u0433\u043e\u043c \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 VDOM \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0438\u043f\u0430 \u0443\u0437\u043b\u0430 \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0438, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0441 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u0412\u043d\u0443\u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0431\u0443\u0434\u0435\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c, \u043a\u0430\u043a\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c\u0441\u044f \u0438 \u0441 \u043a\u0430\u043a\u0438\u043c\u0438 \u043f\u0440\u043e\u043f\u0441\u0430\u043c\u0438. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u0434\u043b\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0443\u0437\u043b\u0430 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0438\u0436\u0435.<\/p>\n<pre><code class=\"javascript\">export interface VDOMComponent {   kind: 'component'   instance?: Component&lt;any, any>   props: object   component: { new(): Component&lt;any, any> }   key: string | number }  export type VDomNode =    | VDOMText   | VDOMElement   | VDOMComponent<\/code><\/pre>\n<p><em>\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f VDOM \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432.<\/em><\/p>\n<p>\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u043e instance \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u0412 \u043d\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0438 \u0442.\u0434. \u0432\u043d\u0443\u0442\u0440\u0438. \u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 diffing \u043c\u044b \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u044b \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438\u0437 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 \u0432 \u043d\u043e\u0432\u043e\u0435, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u043d\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u043b\u0438\u0441\u044c \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438. \u0412\u0430\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u043e\u0432 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043e\u043d\u0430 \u0432\u0435\u0440\u043d\u0435\u0442 \u0443\u0437\u0435\u043b \u0441\u043e \u0441\u0441\u044b\u043b\u043a\u043e\u0439 \u043d\u0430 \u043a\u043b\u0430\u0441\u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u043f\u0440\u043e\u043f\u0441\u0430. \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c &#171;\u0437\u0430 \u043a\u0443\u043b\u0438\u0441\u0430\u043c\u0438&#187;.<\/p>\n<pre><code class=\"javascript\">export const createComponent = &lt;P extends object>(component: { new(): Component&lt;P, any> }, props: P &amp; { key: string }): VDOMComponent => {   const key = props.key   delete props.key   return ({     component, props, key, kind: 'component'   })   }<\/code><\/pre>\n<p><em>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0443\u0437\u043b\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432 \u0440\u0435\u043d\u0434\u0435\u0440-\u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/em>\u00a0.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432 VDOM &#8212; \u044d\u0442\u043e \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433. \u0422\u0430\u043a\u043e\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u043a\u043e\u0433\u0434\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u0440\u043d\u0435\u0432\u044b\u043c \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0438\u043b\u0438 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0435 \u0435\u0433\u043e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f. \u041f\u043e\u0437\u0436\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u0435\u0441\u043b\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 VDOM.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0434\u0435\u043b\u043e \u0434\u043e\u0445\u043e\u0434\u0438\u0442 \u0434\u043e &#171;\u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f&#187; \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0435\u0449\u0435 \u0434\u0432\u0430 \u0441\u0430\u0431\u043a\u0435\u0439\u0441\u0430: \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0443\u0436\u0435 \u0438\u043d\u0441\u0442\u0430\u043d\u0446\u0438\u0440\u043e\u0432\u0430\u043d \u0438\u043b\u0438 \u0435\u0433\u043e \u0435\u0449\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c. \u0415\u0441\u043b\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0443\u0436\u0435 \u0438\u043c\u0435\u0435\u0442 \u0438\u043d\u0441\u0442\u0430\u043d\u0441, \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442: \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e render \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f VDOM, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u0437 \u043d\u0435\u0433\u043e HTML-\u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c notifyMounted \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0db\/a55\/98d\/0dba5598d9832f89478c82d2ebbc20a1.png\" alt=\"\u0412\u0441\u0435, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043c\u043e\u043d\u0442\u0430\u0436\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 render, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043e \u043c\u0435\u0436\u0434\u0443 \u043e\u0431\u044f\u0437\u0430\u043d\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043a\u043b\u0430\u0441\u0441\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u0421\u0442\u0440\u0435\u043b\u043a\u0438 \u0432\u043d\u0438\u0437 - \u044d\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u044b \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0441\u0442\u0440\u0435\u043b\u043a\u0438 \u0432\u0432\u0435\u0440\u0445 - \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u044b \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u043e\u0432\" title=\"\u0412\u0441\u0435, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043c\u043e\u043d\u0442\u0430\u0436\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 render, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043e \u043c\u0435\u0436\u0434\u0443 \u043e\u0431\u044f\u0437\u0430\u043d\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043a\u043b\u0430\u0441\u0441\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u0421\u0442\u0440\u0435\u043b\u043a\u0438 \u0432\u043d\u0438\u0437 - \u044d\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u044b \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0441\u0442\u0440\u0435\u043b\u043a\u0438 \u0432\u0432\u0435\u0440\u0445 - \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u044b \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u043e\u0432\" width=\"875\" height=\"222\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0db\/a55\/98d\/0dba5598d9832f89478c82d2ebbc20a1.png\"\/><figcaption>\u0412\u0441\u0435, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043c\u043e\u043d\u0442\u0430\u0436\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 render, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043e \u043c\u0435\u0436\u0434\u0443 \u043e\u0431\u044f\u0437\u0430\u043d\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043a\u043b\u0430\u0441\u0441\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u0421\u0442\u0440\u0435\u043b\u043a\u0438 \u0432\u043d\u0438\u0437 &#8212; \u044d\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u044b \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0441\u0442\u0440\u0435\u043b\u043a\u0438 \u0432\u0432\u0435\u0440\u0445 &#8212; \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u044b \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u043e\u0432<\/figcaption><\/figure>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432\u0441\u0435 \u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0448\u0430\u0433\u043e\u0432. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 new. \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u043f\u0440\u043e\u043f\u0441\u0443 instance VDOM. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043e\u043d \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0437\u0430\u043d\u043e\u0432\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u043e\u043f\u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u042d\u0442\u043e \u0432\u0435\u0440\u043d\u0435\u0442 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0443\u044e VDOM \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0432 DOM. \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>notifyMounted<\/code>. \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434, \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0434\u0430\u043d\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>renderElement<\/code>, \u043f\u043e\u043a\u0430\u0437\u0430\u043d \u043d\u0438\u0436\u0435.<\/p>\n<pre><code class=\"javascript\">const renderElement = (rootNode: VDomNode): HTMLElement | Text => {   \/\/  render text nodes    if(rootNode.kind == 'component') {     if(rootNode.instance) {       const elem = renderElement(rootNode.instance.render())       rootNode.instance.notifyMounted(elem as HTMLElement)       return elem     }      rootNode.instance = new rootNode.component()     const elem = renderElement( rootNode.instance.initProps(rootNode.props))     rootNode.instance.notifyMounted(elem as HTMLElement)     return elem   }    \/\/ render elements }<\/code><\/pre>\n<p><em>\u041c\u043e\u043d\u0442\u0430\u0436 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/em><\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e, \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u041f\u0435\u0440\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 &#8212; initProps. \u041e\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e props \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e render. \u041e\u043d \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442 \u0438 \u0432\u0435\u0440\u043d\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u0434\u0435\u0440\u0435\u0432\u043e VDOM \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435. \u0417\u0430\u0442\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0435\u0433\u043e \u0432 DOM.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6d9\/658\/ecf\/6d9658ecfc504d596d0acaf745c04297.png\" width=\"851\" height=\"270\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6d9\/658\/ecf\/6d9658ecfc504d596d0acaf745c04297.png\"\/><figcaption><\/figcaption><\/figure>\n<p><em>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u043f\u0441\u043e\u0432 \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435.<\/em><\/p>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, &#8212; \u044d\u0442\u043e <code>notifyMounted<\/code>. \u042d\u0442\u043e \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 (<code>callback<\/code>), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d render (\u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0447\u0435\u0440\u0435\u0437 <code>applyUpdate<\/code>) \u0432 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c HTML-\u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 VDOM. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u0437\u043e\u0432\u0435\u0442 <code>componentDidMount<\/code>, \u0445\u0443\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432 DOM. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>setTimeout<\/code>, \u0447\u0442\u043e\u0431\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u0445\u0443\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442 \u043c\u043e\u043d\u0442\u0430\u0436 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u0430 \u043d\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043d\u0435\u0433\u043e.<\/p>\n<pre><code class=\"javascript\">export abstract class Component&lt;P, S> {    public notifyMounted(elem: HTMLElement) {     this.mountedElement = elem     setTimeout(() => this.componentDidMount())   }        public componentDidMount() {} }<\/code><\/pre>\n<p><em>\u041a\u043e\u043b\u043b\u0431\u044d\u043a \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0438 \u0445\u0443\u043a <\/em><code>componentDidUpdate<\/code><em>.<\/em><\/p>\n<h4>5.3 \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432 DOM, \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f \u0438\u0445 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435\u043c. \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438: \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0435 <code>state<\/code> \u0438\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0435 props \u043e\u0442 \u0441\u0432\u043e\u0435\u0433\u043e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f. \u0412 \u043f\u0435\u0440\u0432\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0432 DOM, \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c &#8212; \u043e\u043d \u0432\u0435\u0440\u043d\u0435\u0442 <code>diff<\/code> \u0441\u0432\u043e\u0435\u043c\u0443 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044e.<\/p>\n<p>\u0412 \u043e\u0431\u043e\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u0445\u043e\u0436: \u043c\u044b \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0441\u043e\u0437\u0434\u0430\u0435\u043c diff \u0441 \u044d\u0442\u0438\u043c \u043d\u043e\u0432\u044b\u043c \u0434\u0435\u0440\u0435\u0432\u043e\u043c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c <code>currentRootNode<\/code> \u043d\u043e\u0432\u044b\u043c \u0434\u0435\u0440\u0435\u0432\u043e\u043c VDOM \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c diff. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0430 \u043d\u0438\u0436\u0435. \u041c\u0435\u0442\u043e\u0434 <code>getUpdateDiff<\/code> \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a <code>setState<\/code> \u0438 <code>setProps<\/code> \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442 \u0442\u044f\u0436\u0435\u043b\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u043f\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u044c\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u0418\u043c\u0435\u043d\u043d\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u0437\u043e\u0432 <code>componentDidUpdate<\/code> \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e.<\/p>\n<pre><code class=\"javascript\">export abstract class Component&lt;P, S> {    private getUpdateDiff() : VDomNodeUpdater {     const newRootNode = this.render()     const diff = createDiff(this.currentRootNode, newRootNode)     if(diff.kind == 'replace') elem => this.mountedElement = elem     this.currentRootNode = newRootNode     setTimeout(() => this.componentDidUpdate())     return diff   } }<\/code><\/pre>\n<p><em>\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0442\u0435\u043a\u0443\u0449\u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/em><\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432\u0438\u0434\u043d\u043e\u00a0 <code>callback<\/code> \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 <code>replace<\/code>. \u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>mountedElement<\/code> \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 HTML-\u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0437\u0430\u043c\u0435\u043d\u044b \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0439 \u043a VDOM \u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0443:<\/p>\n<pre><code class=\"javascript\">export const applyUpdate = (elem: HTMLElement | Text, diff: VDomNodeUpdater): HTMLElement | Text => {   if (diff.kind == 'skip') return elem     if (diff.kind == 'replace') {     const newElem = renderElement(diff.newNode)     elem.replaceWith(newElem)     if(diff.callback) diff.callback(newElem)     return newElem   }      \/\/ rest of the function }<\/code><\/pre>\n<pre><code class=\"javascript\">interface ReplaceOperation {   kind: 'replace',   newNode: VDomNode   callback?: (elem: HTMLElement | Text) => void }<\/code><\/pre>\n<p><em>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 <\/em><code>replace<\/code><em> \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <\/em><code>applyUpdate<\/code>.<\/p>\n<h4>5.4 \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e setState<\/h4>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>setState<\/code>, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e: \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e state; \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c diff \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>getUpdateDiff<\/code>; \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u044d\u0442\u043e\u0442 diff \u043a <code>mountedElement<\/code>. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b if-\u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0435 \u0441\u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432\u044b\u043a\u0438\u0434\u044b\u0432\u0430\u043b\u0430\u0441\u044c \u043e\u0448\u0438\u0431\u043a\u0430. \u0418\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f, \u0442\u043e\u0433\u0434\u0430 \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0432 <code>initProps<\/code>. \u041c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0442\u044c \u044d\u0442\u043e \u043a\u0430\u043a \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 \u043e\u0442 React. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0432\u0441\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0441\u0442\u0430\u043b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u043c \u0438 \u043f\u0440\u043e\u0441\u0442\u044b\u043c:<\/p>\n<pre><code class=\"javascript\">export abstract class Component&lt;P, S> {    protected setState(updater: (s:S) => S) {     if(this.mountedElement == undefined) throw new Error(\"you are updating an unmounted component\")     this.state = updater(this.state)     applyUpdate(this.mountedElement, this.getUpdateDiff())   } }<\/code><\/pre>\n<p><em>\u041c\u0435\u0442\u043e\u0434 <\/em><code>setState<\/code><em> \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432.<\/em><\/p>\n<h4>5.5 \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e setProps<\/h4>\n<p>\u0414\u0440\u0443\u0433\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <code>setProps<\/code>. \u041e\u043d \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 <code>setState<\/code>. \u0415\u0433\u043e \u043f\u043e\u043b\u043d\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u043d\u0438\u0436\u0435. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0435\u0441\u043b\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0435\u0449\u0435 \u043d\u0435 \u0441\u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d. \u041e\u0434\u043d\u043e \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0445\u0443\u043a\u043e\u0432 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 React \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u043c <code>componentWillRecieveProps<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u044b \u0437\u0430\u043d\u043e\u0432\u043e \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441 \u043d\u043e\u0432\u044b\u043c\u0438 \u043f\u0440\u043e\u043f\u0441\u0430\u043c\u0438.<\/p>\n<pre><code class=\"javascript\">export abstract class Component&lt;P, S> {    public setProps(props: P): VDomNodeUpdater {     if(this.mountedElement == null)       throw new Error(\"You are setting the props of an inmounted component\")      this.state = this.componentWillRecieveProps(props, this.state)     this.props = props     return this.getUpdateDiff()   } }<\/code><\/pre>\n<p><em>\u041c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u043f\u0441\u043e\u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430.<\/em><\/p>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 <code>setState<\/code>, <code>setProps<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 diffing, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u043f\u0441\u044b \u0443\u0437\u043b\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c. \u0427\u0442\u043e\u0431\u044b \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0438\u0442\u044c \u044d\u0442\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0432 diffing. \u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 3 \u0432\u0435\u0449\u0438: \u043c\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0434\u0435\u043c\u043e\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0438\u043b\u0438 \u043c\u043e\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0439.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/134\/919\/ee0\/134919ee098ac9713c90d61b24b01f3d.png\" alt=\"\u041e\u0431\u0437\u043e\u0440 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0441 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c. \u0420\u043e\u0434\u0438\u0442\u0435\u043b\u044c \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 diff VDOM \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435\u0441\u0435\u0442 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0437\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 diff'\u043e\u0432, \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c.\" title=\"\u041e\u0431\u0437\u043e\u0440 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0441 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c. \u0420\u043e\u0434\u0438\u0442\u0435\u043b\u044c \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 diff VDOM \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435\u0441\u0435\u0442 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0437\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 diff'\u043e\u0432, \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c.\" width=\"875\" height=\"182\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/134\/919\/ee0\/134919ee098ac9713c90d61b24b01f3d.png\"\/><figcaption>\u041e\u0431\u0437\u043e\u0440 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0441 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c. \u0420\u043e\u0434\u0438\u0442\u0435\u043b\u044c \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 diff VDOM \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435\u0441\u0435\u0442 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0437\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 diff&#8217;\u043e\u0432, \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c.<\/figcaption><\/figure>\n<p>\u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, &#8212; \u044d\u0442\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u041f\u0435\u0440\u0432\u044b\u043c \u0448\u0430\u0433\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 \u0438\u0437 <code>oldNode<\/code> \u0432 <code>newNode<\/code>. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c \u043b\u0438 props, \u0435\u0441\u043b\u0438 \u0434\u0430, \u0442\u043e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c props \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 diff \u0438 \u0435\u0441\u0442\u044c \u0442\u043e\u0442 diff, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 props \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f, \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e skip .<\/p>\n<pre><code class=\"javascript\">export const createDiff = (oldNode: VDomNode, newNode: VDomNode): VDomNodeUpdater => {   \/\/ diff text nodes        if(oldNode.kind == 'component' &amp;&amp; newNode.kind == 'component' &amp;&amp; oldNode.component == newNode.component &amp;&amp; oldNode.instance) {     newNode.instance = oldNode.instance     if(isEqual(oldNode.props, newNode.props)) return skip()     return newNode.instance.setProps(newNode.props)   }    \/\/ diff elements }<\/code><\/pre>\n<p><em>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 props \u0434\u043b\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 diffing-\u043a\u043e\u0434\u0430<\/em>.<\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c, &#8212; \u044d\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0430 \u043b\u044e\u0431\u043e\u0433\u043e \u0443\u0437\u043b\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c. \u042d\u0442\u043e \u0432\u0435\u0441\u044c\u043c\u0430 \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u0443\u0436\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u0439 \u043d\u0430\u043c\u0438 \u043c\u043e\u043d\u0442\u0430\u0436, \u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u043d \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 diffing \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 <code>replace<\/code>. \u041f\u0440\u0438\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>callback<\/code> \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 <code>replace<\/code>, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e <code>notifyMounted<\/code> \u0432\u0441\u0435 \u0435\u0449\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<pre><code class=\"javascript\">export const createDiff = (oldNode: VDomNode, newNode: VDomNode): VDomNodeUpdater => {      \/\/ updating components    if(newNode.kind == 'component') {     newNode.instance = new newNode.component()     return {        kind: 'replace',        newNode: newNode.instance.initProps(newNode.props),       callback: e => newNode.instance.notifyMounted(e)     }   }      \/\/ diffing elements }<\/code><\/pre>\n<p><em>\u041c\u043e\u043d\u0442\u0430\u0436 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 diffing.<\/em><\/p>\n<h4>5.6 \u0414\u0435\u043c\u043e\u043d\u0442\u0430\u0436 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 &#8212; \u044d\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439. \u042d\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a &#171;\u0434\u0435\u043c\u043e\u043d\u0442\u0430\u0436\u0443&#187; \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u0414\u043e\u043b\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0449\u0435\u0439: \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>unmount<\/code>\u00a0 \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0445\u0443\u043a <code>componentWillUnmount<\/code>, \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043e\u0431\u043d\u0443\u043b\u044f\u0435\u0442 \u0441\u0432\u043e\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 DOM \u0438 \u043c\u044b \u0443\u0434\u0430\u043b\u044f\u0435\u043c HTML-\u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438\u0437 DOM.<\/p>\n<pre><code class=\"javascript\">const removeUntilkey = (operations: ChildUpdater[], elems: [string | number, VDomNode][], key: string | number) => {   while(elems[0] &amp;&amp; elems[0][0] != key) {     if(elems[0][1].kind == 'component') {       elems[0][1].instance.unmount()       elems[0][1].instance = null     }     operations.push(remove())     elems.shift()   } }<\/code><\/pre>\n<pre><code class=\"javascript\">export const createDiff = (oldNode: VDomNode, newNode: VDomNode): VDomNodeUpdater => {    \/\/ update component props    if(oldNode.kind == 'component') {     oldNode.instance.unmount()     oldNode.instance = null     return replace(newNode)   }    \/\/ mount new components }<\/code><\/pre>\n<p><em>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 diffing-\u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0442\u0430\u0436\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u044b.<\/em><\/p>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043d\u0430\u0448\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435, &#8212; \u044d\u0442\u043e unmount. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0445\u0443\u043a <code>componentWillUnmount<\/code>, \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0431\u0435\u0437 <code>setTimeout<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0445\u0443\u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0434\u043e \u043d\u0430\u0447\u0430\u043b\u0430 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u043c\u043e\u043d\u0442\u0430\u0436\u0430. \u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0434\u043b\u044f <code>mountedElement<\/code> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 null. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u0434\u0432\u0443\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c: \u043b\u044e\u0431\u044b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0443, \u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u0435 HTML-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043c\u0443\u0441\u043e\u0440\u0430.<\/p>\n<pre><code class=\"javascript\">export abstract class Component&lt;P, S> {        public unmount() {     this.componentWillUnmount()     this.mountedElement = null   }        public componentWillUnmount() { } }<\/code><\/pre>\n<p><em>\u0414\u0435\u043c\u043e\u043d\u0442\u0430\u0436 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430.<\/em><\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043a\u043e\u0434 \u043d\u0430\u0448\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432\u0441\u0435 \u0438\u043c\u0435\u044e\u0449\u0438\u0435\u0441\u044f \u0443 \u043d\u0430\u0441 \u0447\u0430\u0441\u0442\u0438, \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u0434\u043d\u043e\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h3>6. \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u042f \u043f\u043e\u043a\u0430\u0436\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438\u0437 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438. \u041a\u0430\u043a \u0438 \u0432 \u043b\u044e\u0431\u043e\u043c \u0434\u0440\u0443\u0433\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u044d\u0442\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0441\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u0434\u0430\u0447 (todo-list). \u041f\u0435\u0440\u0432\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u0430\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0444\u043e\u0440\u043c\u0443 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u0412\u0442\u043e\u0440\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432 \u0441\u0432\u043e\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438.<\/p>\n<pre><code class=\"javascript\">interface NewItemFormState {     name: string }  interface NewItemFormProps {     addItem: (name: string) => void }  class NewItemForm extends Component&lt;NewItemFormProps, NewItemFormState> {      state = { name: '' }      render() {         return createElement(             'form',             { key: 'f',               onsubmit: (e: Event) => {                 e.preventDefault()                 this.props.addItem(this.state.name)                 this.setState(() => ({ name: '' }))               }             },             createElement('label', { key: 'l-n', 'for': 'i-n' }, createText('New item')),             createElement('input',                 { key: 'i-n', id: 'i-n',                    value: this.state.name,                   oninput: (e: any) => this.setState(s => ({...s, name: e.target.value})) }             ),         )     } }<\/code><\/pre>\n<p><em>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0439 \u0444\u043e\u0440\u043c\u044b \u0441 \u043d\u0430\u0448\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/em><\/p>\n<pre><code class=\"javascript\">class ToDoComponent extends Component&lt;{}, ToDoState> {      state: ToDoState = { items: [] }      toggleItem(index: number) {         this.setState(s => ({items: s.items.map((item, i) => {             if(index == i) return { ...item, done: !item.done }             return item         })}))     }      render() {         return createElement('div', { key: 'root'},             createComponent(NewItemForm, {                 key: 'form',                 addItem: n => this.setState(s => ({ items: s.items.concat([{name: n, done: false}])}))             }),             createElement('ul', { key: 'items' },                  ...this.state.items.map((item: ToDoItem, i) =>                      createElement( 'li', { key: i.toString()},                         createElement('button', {                                  key: 'btn',                                 onclick: () => this.toggleItem(i)                             },                              createText(item.done ? 'done' : '-')),                         createText(item.name, 'label')                 ))             )         )     }<\/code><\/pre>\n<p><em>\u041f\u0440\u043e\u0441\u0442\u043e\u0435 todo-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u043d\u0430\u0448\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/em><\/p>\n<p>\u0417\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 JSX, \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0437\u043d\u0430\u043a\u043e\u043c \u0442\u0435\u043c, \u043a\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441 React. \u041d\u0430\u0448\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 React \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438.<\/p>\n<h3>7. \u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c. \u041f\u043e\u043b\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 <a href=\"https:\/\/github.com\/WimJongeneel\/ts-reactive-rendering\"><u>\u044d\u0442\u043e\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/u><\/a>.<\/p>\n<hr\/>\n<p>React-hooks \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0432 React \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 16.8, \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043e\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0443\u0436\u0435 \u043f\u043e\u0432\u0441\u0435\u043c\u0435\u0441\u0442\u043d\u043e. \u041f\u0440\u0438\u0433\u043b\u0430\u0448\u0430\u0435\u043c \u0432\u0441\u0435\u0445 \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0438\u043d\u0442\u0435\u043d\u0441\u0438\u0432, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 React-hooks, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c hooks, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u0443\u0447\u0438\u043c\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 hooks. \u041f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 react-testing-library \u0438 \u043d\u0430\u0443\u0447\u0438\u043c\u0441\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 hooks. \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f <a href=\"https:\/\/otus.pw\/T3n6\/\">\u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435. <\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/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\/company\/otus\/blog\/653861\/\"> https:\/\/habr.com\/ru\/company\/otus\/blog\/653861\/<\/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_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u0414\u0435\u043c\u0438\u0441\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f React \u043f\u0443\u0442\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 DOM, \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438 \u0445\u0443\u043a\u0438 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430  <\/h2>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u0438\u0434\u043d\u044b \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0415\u0441\u043b\u0438 \u0440\u0430\u043d\u044c\u0448\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0430 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0438\u0441\u044c \u043b\u0438\u0448\u044c \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438, \u0442\u043e \u0432 \u043d\u0430\u0448\u0438 \u0434\u043d\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0438\u0437 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0425\u043e\u0442\u044f \u043c\u043d\u043e\u0433\u0438\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442 \u0442\u0430\u043a\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043a\u0430\u043a React \u0438\u043b\u0438 Vue, \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0438\u0445 \u0442\u043e\u0447\u043d\u043e\u0439 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0448\u0438\u0440\u043e\u043a\u043e \u0438\u0437\u0443\u0447\u0435\u043d\u043e. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0438 \u0440\u0430\u0437\u044a\u044f\u0441\u043d\u044e, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c.<\/p>\n<p>\u041d\u043e \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043c\u044b \u043d\u0430\u0447\u043d\u0435\u043c, \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435. \u0425\u043e\u0442\u044f \u043d\u0430\u0448\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0432\u043f\u043e\u043b\u043d\u0435 \u0440\u0430\u0431\u043e\u0447\u0430\u044f (\u0441\u043c. \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 \u043a\u043e\u043d\u0446\u0435), \u044d\u0442\u043e, \u043f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e, \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u0430 \u043d\u0435 \u043b\u0435\u0433\u043a\u043e\u0432\u0435\u0441\u043d\u0430\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 React. \u0412\u0435\u0441\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0430 <a href=\"https:\/\/github.com\/WimJongeneel\/ts-reactive-rendering\"><u>GitHub<\/u><\/a>.<\/p>\n<h3>1. \u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430<\/h3>\n<p>\u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u0432 \u043b\u044e\u0431\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 &#8212; \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u0420\u0430\u0431\u043e\u0442\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u043c &#171;\u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e\u043c&#187;. \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e (&#171;state&#187;) \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0435\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432 DOM. \u0417\u0434\u0435\u0441\u044c \u0443\u0436\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f, \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0435 \u0432\u0430\u043c \u043f\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e react-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 : <code>this.state<\/code>, <code>this.setState<\/code> \u0438 <code>render<\/code>.<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u041a\u0430\u0436\u0434\u0430\u044f \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0446\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u043e\u0435 state (\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435), \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u043d\u043e\u0432\u0443\u044e VDOM, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0449\u0443\u044e HTML \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<p>\u041a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u043c \u0432 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u043c\u044b\u0448\u043b\u0435\u043d\u0438\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 DOM \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0432\u0435\u0449\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u0435 jQuery). \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u043e\u0434\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0438 \u043e\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u0425\u043e\u0442\u044f \u0438\u0434\u0435\u044f &#171;\u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430&#187; \u0432\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u0430 (\u043c\u0435\u043d\u044c\u0448\u0435 \u043a\u043e\u0434\u0430, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 DOM \u0438 \u0442.\u0434.), \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0434\u0440\u0443\u0433\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430: \u0435\u0441\u043b\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c \u0432\u0441\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 DOM \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438, \u044d\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043d\u0435\u0443\u0434\u043e\u0431\u0441\u0442\u0432. \u041f\u043e\u043c\u0438\u043c\u043e \u043f\u043e\u0442\u0435\u0440\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u044d\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043a \u0443\u0442\u0440\u0430\u0442\u0435 \u0444\u043e\u043a\u0443\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c, \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u043c \u0441\u043a\u0430\u0447\u043a\u0430\u043c \u043f\u0440\u0438 \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0435 \u0438 \u0442.\u0434.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u044d\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e DOM \u0441 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f (diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c) \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u0442\u0435\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0430 \u043a \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 DOM. \u0412\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 DOM \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0432\u0441\u0435, \u0447\u0442\u043e \u0437\u0430\u0445\u043e\u0442\u0438\u043c, \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 JavaScript \u0441 \u043f\u0440\u0438\u0447\u0443\u0434\u043b\u0438\u0432\u044b\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c, \u0430 \u043d\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u0430\u044f DOM. \u0418 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u043c\u043d\u043e\u0433\u043e diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u043c\u043e\u0436\u043d\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u0443\u044e DOM \u0432\u043d\u0435\u0441\u0435\u043d\u043e \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0442\u0430\u043a\u0443\u044e \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e DOM \u0434\u0430\u0436\u0435 \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0439, \u0447\u0435\u043c \u043b\u044e\u0431\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f DOM, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0442\u0430\u043a\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 DOM. \u041e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0449\u0435 \u0442\u043e\u0439, \u0447\u0442\u043e \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435 React, \u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0438, \u0447\u0442\u043e \u0432\u0430\u0436\u043d\u043e, \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 DOM. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0438 \u043f\u0440\u043e\u043f\u0441\u0430\u043c\u0438, \u0438 \u0442\u043e, \u043a\u0430\u043a \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f \u0442\u0430\u043a\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043e\u0431\u044b\u0433\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 DOM. \u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<h3>2. \u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f DOM<\/h3>\n<p>\u041f\u043e \u0441\u0432\u043e\u0435\u0439 \u0441\u0443\u0442\u0438 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f DOM \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0434\u0430\u043d\u043d\u044b\u0445: \u0434\u0435\u0440\u0435\u0432\u0430 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 HTML \u0438 diff-\u0434\u0435\u0440\u0435\u0432\u0430. \u0414\u0435\u0440\u0435\u0432\u043e HTML \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 HTML \u0432 JavaScript-\u043e\u0431\u044a\u0435\u043a\u0442\u0435 . \u042d\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f \u043c\u0435\u0442\u043e\u0434\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u0442\u043e, \u0441 \u0447\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443. Diff-\u0434\u0435\u0440\u0435\u0432\u043e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442, \u043a\u0430\u043a\u0438\u0435 \u0448\u0430\u0433\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 HTML \u0438\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0435.<\/p>\n<figure class=\"full-width\"><figcaption>\u0421\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 VDOM-\u0434\u0435\u0440\u0435\u0432\u044c\u044f\u043c\u0438, diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c \u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u043e\u0439 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f (diff)\u00a0<\/figcaption><\/figure>\n<h4>2.1 \u0414\u0435\u0440\u0435\u0432\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 HTML<\/h4>\n<p>\u042d\u0442\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 DOM. \u041f\u043e\u043a\u0430 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0443\u0437\u043b\u044b. \u041f\u043e\u0437\u0436\u0435 \u044d\u0442\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u0441\u044f, \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0435\u0439\u0442\u0444\u0443\u043b-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u0434\u0435\u0440\u0435\u0432\u0430. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043e \u043d\u0438\u0436\u0435. \u0421\u0432\u043e\u0439\u0441\u0442\u0432\u043e key \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0442\u0435, \u043a\u0442\u043e \u0437\u043d\u0430\u043a\u043e\u043c \u0441 React, \u0443\u0436\u0435 \u043f\u043e\u043d\u044f\u043b\u0438 \u044d\u0442\u043e.<\/p>\n<pre><code class=\"javascript\">export type VDOMAttributes = { [_: string]: string | number | boolean | Function }  export interface VDOMElement {   kind: 'element'   tagname: string   childeren?: VDomNode[]   props?: VDOMAttributes   key: string | number }  export interface VDOMText {   kind: 'text',   value: string   key: string | number }  export type VDomNode =  | VDOMText | VDOMElement<\/code><\/pre>\n<p><em>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 VDOM.<\/em><\/p>\n<p>\u041d\u0430\u0448\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c JSX, \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u0445\u0435\u043b\u043f\u0435\u0440\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 VDOM \u0443\u0434\u043e\u0431\u043d\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c. \u041e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043d\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u043e\u0432 React.createElement, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0432\u044b, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0438\u0441\u044c \u0432 \u0441\u0432\u043e\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u0430\u0445 JavaScript.<\/p>\n<pre><code class=\"javascript\">export const createElement = (tagname: string, props: VDOMAttributes &amp; { key: string }, ...childeren: VDomNode[]): VDOMElement => {   const key = props.key   delete props.key   return ({ kind: 'element',     tagname, props,     childeren, key   }) }  export const createText = (value: string | number | boolean, key: string = '') : VDOMText => ({   key, kind: 'text', value: value.toString() })<\/code><\/pre>\n<p><em>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 VDOM.<\/em><\/p>\n<h4>2.2 \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 diff<\/h4>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f (diffing), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043e\u0434\u043d\u0438\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c, \u0430 \u0437\u0430\u0442\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u043c \u0435\u0433\u043e \u0437\u0430 \u0441\u0447\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0438\u043f \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f &#8212; \u044d\u0442\u043e \u043c\u0443\u0442\u0430\u0446\u0438\u044f DOM, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0430 \u0441 \u043e\u0434\u043d\u0438\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c HTML. \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f update \u0438 replace. \u0422\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c skip, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u043d\u0430 \u043e\u0442\u043a\u0430\u0437 \u043e\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439.<\/p>\n<pre><code>type AttributesUpdater = {   set: VDOMAttributes   remove: string[] }  interface UpdateOperation {   kind: 'update',   attributes: AttributesUpdater,   childeren: ChildUpdater[] }  interface ReplaceOperation {   kind: 'replace',   newNode: VDomNode }  interface SkipOperation {    kind: 'skip'  }  export type VDomNodeUpdater =    | UpdateOperation   | ReplaceOperation   | SkipOperation<\/code><\/pre>\n<p><em>\u0422\u0438\u043f\u044b \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0445 \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443.<\/em><\/p>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f update \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 diff-\u0434\u0435\u0440\u0435\u0432\u043e \u0438 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0448\u0430\u0433\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 setState. \u0422\u0430\u043a\u0436\u0435 \u0437\u0434\u0435\u0441\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u043a \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u041f\u043e\u043c\u0438\u043c\u043e \u0442\u0435\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0443\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438, \u043e\u043d\u0438 \u0442\u0430\u043a\u0436\u0435 \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442 insert \u0438 remove:<\/p>\n<pre><code>interface RemoveOperation {   kind: 'remove' }  interface InsertOperation {   kind: 'insert',    node: VDomNode }  export type ChildUpdater =   | UpdateOperation   | ReplaceOperation   | RemoveOperation   | SkipOperation   | InsertOperation<\/code><\/pre>\n<p><em>\u0422\u0438\u043f\u044b \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u044b \u043a \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c<\/em>.<\/p>\n<h3>3. \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 diff&#8217;\u043e\u0432<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e DOM \u0438 diff, \u0434\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u043e, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 VDOM \u0441\u0442\u043e\u044f\u0449\u0438\u043c \u0443\u0441\u0438\u043b\u0438\u0439: diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c . \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u0448\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0435, \u044d\u0442\u043e \u0432\u0430\u0436\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u0440\u0435\u0447\u044c \u043e \u043f\u043b\u0430\u0432\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0439 \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0438\u0441\u0442\u044b\u0439 diffing-\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043e\u043f\u044b\u0442 \u043b\u044e\u0431\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0442\u043e\u0433\u043e, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u044b \u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<p>\u041c\u044b \u0440\u0430\u0437\u043b\u043e\u0436\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043d\u0430 \u0434\u0432\u0435 \u0447\u0430\u0441\u0442\u0438: \u0441\u043d\u0430\u0447\u0430\u043b\u0430 diffing \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u043f\u043e\u0442\u043e\u043c diffing \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 (\u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445) \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u043b\u043e\u0441\u044c \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0439 \u0442\u0438\u043f\u043e\u0432.<\/p>\n<h4>3.1 \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 diff&#8217;\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430<\/h4>\n<p>\u041f\u0440\u0438 diffing&#8217;\u0435 VDOM \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0434\u0435\u043b\u043e \u0441 \u0434\u0432\u0443\u043c\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0432\u0435\u0449\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f: \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0443\u0437\u043b\u044b \u0438 HTML-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b. \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u0443\u0437\u043b\u043e\u0432, \u0442.\u043a. \u043e\u043d\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b. \u0415\u0441\u043b\u0438 \u043e\u0431\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u043c\u0438 \u0443\u0437\u043b\u0430\u043c\u0438 \u0438 \u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c, \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e skip. \u0412 \u043b\u044e\u0431\u043e\u043c \u0434\u0440\u0443\u0433\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u0433\u0434\u0430 \u0435\u0441\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0443\u0437\u0435\u043b, \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043d\u043e\u0432\u044b\u043c:<\/p>\n<pre><code class=\"javascript\">export const createDiff = (oldNode: VDomNode, newNode: VDomNode): VDomNodeUpdater => {   \/\/ skip over text nodes with the same text   if (oldNode.kind == 'text' &amp;&amp; newNode.kind == 'text' &amp;&amp; oldNode.value == newNode.value) {     return skip()   }    \/\/ If a textnode is updated we need to replace it completly   if (oldNode.kind == 'text' || newNode.kind == 'text') {       return replace(newNode)   }   \/\/ rest of the diffing }<\/code><\/pre>\n<p><em>Diffing \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u0443\u0437\u043b\u043e\u0432.<\/em><\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u043c\u044b \u0443\u0431\u0435\u0434\u0438\u043b\u0438\u0441\u044c, \u0447\u0442\u043e \u043e\u0431\u0430 \u0443\u0437\u043b\u0430 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438. \u041d\u043e \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u043e\u0434\u0438\u043d \u0441\u043b\u0443\u0447\u0430\u0439, \u0433\u0434\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0443\u0437\u0435\u043b: \u043a\u043e\u0433\u0434\u0430 tagname \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f. \u042d\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435,\u0447\u0442\u043e \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043d\u0430\u0448\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e:<\/p>\n<pre><code class=\"javascript\">export const createDiff = (oldNode: VDomNode, newNode: VDomNode): VDomNodeUpdater => {   \/\/ diff text nodes      \/\/ If the tagname of a node is changed we have to replace it completly   if (oldNode.tagname != oldNode.tagname) {     return replace(newNode)   }    \/\/ diff elements }<\/code><\/pre>\n<p><em>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0435 <\/em><code>tagname<\/code><em> \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0432\u0435\u0441\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d \u0437\u0430\u043d\u043e\u0432\u043e.<\/em><\/p>\n<p>\u0414\u0432\u0430 \u0438\u043c\u0435\u044e\u0449\u0438\u0445\u0441\u044f \u0443 \u043d\u0430\u0441 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438\u043c\u0435\u044e\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0442\u0438\u043f \u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u044b \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0435 \u0431\u0435\u0437 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c: \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u044b; \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u044b; \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432:<\/p>\n<pre><code class=\"javascript\">export const createDiff = (oldNode: VDomNode, newNode: VDomNode): VDomNodeUpdater => {   \/\/ diff text nodes and replaced elements      \/\/ get the updated and replaced attributes   const attUpdater: AttributesUpdater = {     remove: Object.keys(oldNode.props || {})       .filter(att => Object.keys(newNode).indexOf(att) == -1),     set: Object.keys(newNode.props || {})       .filter(att => oldNode.props[att] != newNode.props[att])       .reduce((upd, att) => ({ ...upd, [att]: newNode.props[att] }), {})   }    const childsUpdater: ChildUpdater[] = childsDiff((oldNode.childeren || []), (newNode.childeren || []))    return update(attUpdater, childsUpdater) }<\/code><\/pre>\n<p><em>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u0441\u0435\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f.<\/em><\/p>\n<p>\u041c\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0438 \u043b\u043e\u0433\u0438\u043a\u0443 diffing&#8217;\u0430 \u0434\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 <\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\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-330203","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/330203","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=330203"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/330203\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=330203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=330203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=330203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}