{"componentChunkName":"component---src-templates-docs-js","path":"/docs/lifting-state-up.html","result":{"data":{"markdownRemark":{"html":"<p>Часто кілька компонентів повинні відображати одні і ті ж зміни. Ми рекомендуємо підняти спільний стан до свого найближчого спільного предка. Давайте подивимося, як це працює.</p>\n<p>У цьому розділі ми створимо калькулятор температури, який обчислює чи буде вода закипати при заданій температурі.</p>\n<p>Почнемо з компонента під назвою <code class=\"gatsby-code-text\">BoilingVerdict</code>. Він приймає температуру <code class=\"gatsby-code-text\">celsius</code> як проп і виводить, чи її достатньо для закипання:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">BoilingVerdict</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>celsius <span class=\"token operator\">>=</span> <span class=\"token number\">100</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>p</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Вода закипить.</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>p</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>p</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Вода не закипить.</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>p</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span></span><span class=\"token punctuation\">}</span></code></pre></div>\n<p>Далі ми створимо компонент під назвою <code class=\"gatsby-code-text\">Calculator</code>. Він рендерить <code class=\"gatsby-code-text\">&lt;input&gt;</code>, що дозволяє вводити температуру і зберігає його значення в <code class=\"gatsby-code-text\">this.state.temperature</code>.</p>\n<p>Крім того, він рендерить <code class=\"gatsby-code-text\">BoilingVerdict</code> для поточного введеного значення.</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">Calculator</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">super</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleChange <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">handleChange</span><span class=\"token punctuation\">.</span><span class=\"token function\">bind</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>temperature<span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">handleChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>temperature<span class=\"token operator\">:</span> e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">const</span> temperature <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>temperature<span class=\"token punctuation\">;</span></span>    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>fieldset</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>legend</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Введіть температуру в градусах Цельсія:</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>legend</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span></span><span class=\"gatsby-highlight-code-line\">          <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>temperature<span class=\"token punctuation\">}</span></span></span><span class=\"gatsby-highlight-code-line\">          <span class=\"token attr-name\">onChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleChange<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">BoilingVerdict</span></span></span><span class=\"gatsby-highlight-code-line\">          <span class=\"token attr-name\">celsius</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">parseFloat</span><span class=\"token punctuation\">(</span>temperature<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span></span><span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>fieldset</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><a href=\"https://codepen.io/gaearon/pen/ZXeOBm?editors=0010\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><strong>Спробуйте на CodePen</strong></a></p>\n<h2 id=\"adding-a-second-input\"><a href=\"#adding-a-second-input\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Додавання другого поля вводу </h2>\n<p>Наша нова вимога полягає в тому, що крім поля вводу за Цельсієм, ми надамо можливість вводити температуру за Фаренгейтом, і ці два поля будуть синхронізовані між собою.</p>\n<p>Ми можемо почати з того, що витягнемо компонент <code class=\"gatsby-code-text\">TemperatureInput</code> з <code class=\"gatsby-code-text\">Calculator</code>. До нього додамо проп <code class=\"gatsby-code-text\">scale</code> , який може бути <code class=\"gatsby-code-text\">&quot;c&quot;</code> або <code class=\"gatsby-code-text\">&quot;f&quot;</code>:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">const</span> scaleNames <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">  c<span class=\"token operator\">:</span> <span class=\"token string\">'Цельсій'</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">  f<span class=\"token operator\">:</span> <span class=\"token string\">'Фаренгейт'</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">TemperatureInput</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">super</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleChange <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">handleChange</span><span class=\"token punctuation\">.</span><span class=\"token function\">bind</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>temperature<span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">handleChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>temperature<span class=\"token operator\">:</span> e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> temperature <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>temperature<span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">const</span> scale <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>scale<span class=\"token punctuation\">;</span></span>    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>fieldset</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>legend</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Введіть температуру в градусах </span><span class=\"token punctuation\">{</span>scaleNames<span class=\"token punctuation\">[</span>scale<span class=\"token punctuation\">]</span><span class=\"token punctuation\">}</span><span class=\"token plain-text\">:</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>legend</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>temperature<span class=\"token punctuation\">}</span></span>\n               <span class=\"token attr-name\">onChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleChange<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>fieldset</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Тепер ми можемо змінити <code class=\"gatsby-code-text\">Calculator</code> для рендеру двох окремих полів вводу температури:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">Calculator</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">TemperatureInput</span></span> <span class=\"token attr-name\">scale</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>c<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">TemperatureInput</span></span> <span class=\"token attr-name\">scale</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>f<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span></span><span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><a href=\"https://codepen.io/gaearon/pen/jGBryx?editors=0010\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><strong>Спробуйте на CodePen</strong></a></p>\n<p>Зараз ми маємо два поля вводу, але коли ви вводите температуру в одному з них, інший не оновлюється. Це суперечить нашій вимозі: ми хочемо, щоб вони були синхронізовані.</p>\n<p>Ми також не можемо відобразити <code class=\"gatsby-code-text\">BoilingVerdict</code> з<code class=\"gatsby-code-text\">Calculator</code>. <code class=\"gatsby-code-text\">Calculator</code> не знає поточну температуру, тому що вона прихована всередині <code class=\"gatsby-code-text\">TemperatureInput</code>.</p>\n<h2 id=\"writing-conversion-functions\"><a href=\"#writing-conversion-functions\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Написання функцій перетворення </h2>\n<p>Для початку ми напишемо дві функції для перетворення температури з градусів по Цельсію у градуси по Фаренгейту і навпаки:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">toCelsius</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">fahrenheit</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>fahrenheit <span class=\"token operator\">-</span> <span class=\"token number\">32</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> <span class=\"token number\">5</span> <span class=\"token operator\">/</span> <span class=\"token number\">9</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">toFahrenheit</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">celsius</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>celsius <span class=\"token operator\">*</span> <span class=\"token number\">9</span> <span class=\"token operator\">/</span> <span class=\"token number\">5</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> <span class=\"token number\">32</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Ці дві функції перетворюють числа. Ми напишемо ще одну функцію, яка приймає два аргумента: рядок <code class=\"gatsby-code-text\">temperature</code> і функцію перетворення <code class=\"gatsby-code-text\">convert</code>, і повертає рядок. Ми будемо використовувати його для обчислення значення одного поля вводу на основі іншого.</p>\n<p>Функція повертатиме порожній рядок при помилковому значенні <code class=\"gatsby-code-text\">temperature</code> або рядок, що відповідає значенню, округленому до третього числа після коми:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">tryConvert</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">temperature<span class=\"token punctuation\">,</span> convert</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> input <span class=\"token operator\">=</span> <span class=\"token function\">parseFloat</span><span class=\"token punctuation\">(</span>temperature<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>Number<span class=\"token punctuation\">.</span><span class=\"token function\">isNaN</span><span class=\"token punctuation\">(</span>input<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token string\">''</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">const</span> output <span class=\"token operator\">=</span> <span class=\"token function\">convert</span><span class=\"token punctuation\">(</span>input<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> rounded <span class=\"token operator\">=</span> Math<span class=\"token punctuation\">.</span><span class=\"token function\">round</span><span class=\"token punctuation\">(</span>output <span class=\"token operator\">*</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">/</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> rounded<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Наприклад, <code class=\"gatsby-code-text\">tryConvert(&#39;abc&#39;, toCelsius)</code> повертає порожній рядок і <code class=\"gatsby-code-text\">tryConvert(&#39;10.22&#39;, toFahrenheit)</code> повертає <code class=\"gatsby-code-text\">&#39;50.396&#39;</code>.</p>\n<h2 id=\"lifting-state-up\"><a href=\"#lifting-state-up\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Підйом стану </h2>\n<p>В даний час обидва компоненти <code class=\"gatsby-code-text\">TemperatureInput</code> незалежно зберігають свої значення в локальному стані:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">TemperatureInput</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">super</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleChange <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">handleChange</span><span class=\"token punctuation\">.</span><span class=\"token function\">bind</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>temperature<span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">handleChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>temperature<span class=\"token operator\">:</span> e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">const</span> temperature <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>temperature<span class=\"token punctuation\">;</span></span>    <span class=\"token comment\">// ...  </span></code></pre></div>\n<p>Однак ми хочемо, щоб ці два поля вводу були синхронізовані одне з одним. Коли ми оновлюємо поле Цельсія, поле Фаренгейта повинне відображати перетворену температуру і навпаки.</p>\n<p>Обмін станом у React здійснюється шляхом переміщення його до найближчого спільного предка компонентів, які його потребують. Це називається “підйом стану вгору”. Ми видалимо локальний стан з <code class=\"gatsby-code-text\">TemperatureInput</code> і перемістимо його в <code class=\"gatsby-code-text\">Calculator</code>.</p>\n<p>Якщо <code class=\"gatsby-code-text\">Calculator</code> володіє спільним станом, він стає “джерелом істини” для поточної температури в обох полях вводу. Він може надати їм обом значення, які узгоджуються один з одним. Оскільки пропси обох компонентів <code class=\"gatsby-code-text\">TemperatureInput</code> приходять з одного і того ж батьківського компонента <code class=\"gatsby-code-text\">Calculator</code>, то їх поля вводу завжди будуть синхронізовані.</p>\n<p>Давайте подивимося, як це працює крок за кроком.</p>\n<p>Спершу ми замінимо <code class=\"gatsby-code-text\">this.state.temperature</code> на <code class=\"gatsby-code-text\">this.props.temperature</code> у компоненті <code class=\"gatsby-code-text\">TemperatureInput</code>. Наразі давайте вдамо, що <code class=\"gatsby-code-text\">this.props.temperature</code> вже існує, хоча в майбутньому нам доведеться передавати його з <code class=\"gatsby-code-text\">Calculator</code>:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\">  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// До того: const temperature = this.state.temperature;</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">const</span> temperature <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>temperature<span class=\"token punctuation\">;</span></span>    <span class=\"token comment\">// ...</span></code></pre></div>\n<p>Ми знаємо, що <a href=\"/docs/components-and-props.html#props-are-read-only\">пропси можна тільки читати</a>. Коли <code class=\"gatsby-code-text\">temperature</code> була в локальному стані, в компоненті <code class=\"gatsby-code-text\">TemperatureInput</code> можна було просто викликати <code class=\"gatsby-code-text\">this.setState()</code>, щоб змінити її. Однак тепер, коли <code class=\"gatsby-code-text\">temperature</code> надходить від батьківського компонента як проп, <code class=\"gatsby-code-text\">TemperatureInput</code> не має контролю над ним.</p>\n<p>У React це, як правило, вирішується шляхом створення “контрольованого” компонента. Так само, як DOM-елемент <code class=\"gatsby-code-text\">&lt;input&gt;</code> приймає атрибути <code class=\"gatsby-code-text\">value</code> і <code class=\"gatsby-code-text\">onChange</code>, так і користувацький <code class=\"gatsby-code-text\">TemperatureInput</code> може прийняти пропси <code class=\"gatsby-code-text\">temperature</code> і <code class=\"gatsby-code-text\">onTemperatureChange</code> зі свого батьківського компонента <code class=\"gatsby-code-text\">Calculator</code>.</p>\n<p>Тепер, коли <code class=\"gatsby-code-text\">TemperatureInput</code> “хоче” оновити свою температуру, він викликає <code class=\"gatsby-code-text\">this.props.onTemperatureChange</code>:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\">  <span class=\"token function\">handleChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// До того: this.setState({temperature: e.target.value});</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span><span class=\"token function\">onTemperatureChange</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>    <span class=\"token comment\">// ...</span></code></pre></div>\n<blockquote>\n<p>Примітка:</p>\n<p>Немає спеціального сенсу в іменах <code class=\"gatsby-code-text\">temperature</code> або <code class=\"gatsby-code-text\">onTemperatureChange</code> в користувацьких компонентах. Ми могли б назвати їх будь-як інакше. Наприклад, <code class=\"gatsby-code-text\">value</code> і <code class=\"gatsby-code-text\">onChange</code>, що є загальноприйнятими значеннями.</p>\n</blockquote>\n<p>Проп <code class=\"gatsby-code-text\">onTemperatureChange</code> передасться разом з пропом <code class=\"gatsby-code-text\">temperature</code> від батьківського компонента <code class=\"gatsby-code-text\">Calculator</code>. Він буде обробляти зміни, змінюючи свій власний локальний стан, і таким чином провокувати повторний рендер обох полів вводу з новими значеннями. Незабаром ми розглянемо нову реалізацію <code class=\"gatsby-code-text\">Calculator</code>.</p>\n<p>Перед тим як зануритися в зміни в <code class=\"gatsby-code-text\">Calculator</code>, давайте підсумуємо наші зміни компонента <code class=\"gatsby-code-text\">TemperatureInput</code>. Ми видалили з нього локальний стан і замість <code class=\"gatsby-code-text\">this.state.temperature</code> використовуємо <code class=\"gatsby-code-text\">this.props.temperature</code>. Замість виклику <code class=\"gatsby-code-text\">this.setState()</code>, коли ми хочемо внести зміни, тепер викликаємо <code class=\"gatsby-code-text\">this.props.onTemperatureChange()</code>, який буде отриманий від компонента <code class=\"gatsby-code-text\">Calculator</code>:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">TemperatureInput</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">super</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleChange <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">handleChange</span><span class=\"token punctuation\">.</span><span class=\"token function\">bind</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">handleChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span><span class=\"token function\">onTemperatureChange</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">const</span> temperature <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>temperature<span class=\"token punctuation\">;</span></span>    <span class=\"token keyword\">const</span> scale <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>scale<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>fieldset</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>legend</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Введіть температуру в градусах </span><span class=\"token punctuation\">{</span>scaleNames<span class=\"token punctuation\">[</span>scale<span class=\"token punctuation\">]</span><span class=\"token punctuation\">}</span><span class=\"token plain-text\">:</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>legend</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>temperature<span class=\"token punctuation\">}</span></span>\n               <span class=\"token attr-name\">onChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleChange<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>fieldset</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Тепер перейдемо до компонента <code class=\"gatsby-code-text\">Calculator</code>.</p>\n<p>Ми будемо зберігати значення <code class=\"gatsby-code-text\">temperature</code> і <code class=\"gatsby-code-text\">scale</code> у його локальному стані. Це стан, який ми “підняли” з полів вводу, і він буде служити “джерелом істини” для них обох. Це мінімальне представлення всіх даних, які ми повинні знати, щоб відрендерити обидва поля вводу.</p>\n<p>Наприклад, якщо ми введемо 37 у поле Цельсія, стан компонента <code class=\"gatsby-code-text\">Calculator</code> буде:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token punctuation\">{</span>\n  temperature<span class=\"token operator\">:</span> <span class=\"token string\">'37'</span><span class=\"token punctuation\">,</span>\n  scale<span class=\"token operator\">:</span> <span class=\"token string\">'c'</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Якщо ми пізніше змінимо поле Фаренгейта на 212, стан компонента <code class=\"gatsby-code-text\">Calculator</code> буде:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token punctuation\">{</span>\n  temperature<span class=\"token operator\">:</span> <span class=\"token string\">'212'</span><span class=\"token punctuation\">,</span>\n  scale<span class=\"token operator\">:</span> <span class=\"token string\">'f'</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Ми могли б зберегти значення обох полів, але це непотрібно. Достатньо зберегти значення останнього зміненого поля вводу і шкалу, яку він представляє. Тоді ми можемо зробити висновок про значення іншого поля, виходячи з поточних <code class=\"gatsby-code-text\">temperature</code> і <code class=\"gatsby-code-text\">scale</code>.</p>\n<p>Поля вводу залишаються синхронізованими, оскільки їх значення обчислюються з одного і того ж стану:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">Calculator</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">super</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleCelsiusChange <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">handleCelsiusChange</span><span class=\"token punctuation\">.</span><span class=\"token function\">bind</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleFahrenheitChange <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">handleFahrenheitChange</span><span class=\"token punctuation\">.</span><span class=\"token function\">bind</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>temperature<span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span> scale<span class=\"token operator\">:</span> <span class=\"token string\">'c'</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">handleCelsiusChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">temperature</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>scale<span class=\"token operator\">:</span> <span class=\"token string\">'c'</span><span class=\"token punctuation\">,</span> temperature<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">handleFahrenheitChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">temperature</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>scale<span class=\"token operator\">:</span> <span class=\"token string\">'f'</span><span class=\"token punctuation\">,</span> temperature<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">const</span> scale <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>scale<span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">const</span> temperature <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>temperature<span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">const</span> celsius <span class=\"token operator\">=</span> scale <span class=\"token operator\">===</span> <span class=\"token string\">'f'</span> <span class=\"token operator\">?</span> <span class=\"token function\">tryConvert</span><span class=\"token punctuation\">(</span>temperature<span class=\"token punctuation\">,</span> toCelsius<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> temperature<span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">const</span> fahrenheit <span class=\"token operator\">=</span> scale <span class=\"token operator\">===</span> <span class=\"token string\">'c'</span> <span class=\"token operator\">?</span> <span class=\"token function\">tryConvert</span><span class=\"token punctuation\">(</span>temperature<span class=\"token punctuation\">,</span> toFahrenheit<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> temperature<span class=\"token punctuation\">;</span></span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">TemperatureInput</span></span>\n          <span class=\"token attr-name\">scale</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>c<span class=\"token punctuation\">\"</span></span>\n<span class=\"gatsby-highlight-code-line\">          <span class=\"token attr-name\">temperature</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>celsius<span class=\"token punctuation\">}</span></span></span><span class=\"gatsby-highlight-code-line\">          <span class=\"token attr-name\">onTemperatureChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleCelsiusChange<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span></span><span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">TemperatureInput</span></span>\n          <span class=\"token attr-name\">scale</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>f<span class=\"token punctuation\">\"</span></span>\n<span class=\"gatsby-highlight-code-line\">          <span class=\"token attr-name\">temperature</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>fahrenheit<span class=\"token punctuation\">}</span></span></span><span class=\"gatsby-highlight-code-line\">          <span class=\"token attr-name\">onTemperatureChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleFahrenheitChange<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span></span><span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">BoilingVerdict</span></span>\n<span class=\"gatsby-highlight-code-line\">          <span class=\"token attr-name\">celsius</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">parseFloat</span><span class=\"token punctuation\">(</span>celsius<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span></span><span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><a href=\"https://codepen.io/gaearon/pen/WZpxpz?editors=0010\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><strong>Спробуйте на CodePen</strong></a></p>\n<p>Тепер, незалежно від того, яке поле ви редагуєте, <code class=\"gatsby-code-text\">this.state.temperature</code> і<code class=\"gatsby-code-text\">this.state.scale</code> в <code class=\"gatsby-code-text\">Calculator</code> будуть оновлені. Одне з полів отримає значення, яке ввів користувач, а інше - значення, перераховане на його основі.</p>\n<p>Давайте підсумуємо, що відбувається, коли ви редагуєте поля вводу:</p>\n<ul>\n<li>React викликає функцію, задану як <code class=\"gatsby-code-text\">onChange</code> у DOM-елементі <code class=\"gatsby-code-text\">&lt;input&gt;</code>. У нашому випадку, це метод <code class=\"gatsby-code-text\">handleChange</code> у компоненті <code class=\"gatsby-code-text\">TemperatureInput</code>.</li>\n<li>Метод <code class=\"gatsby-code-text\">handleChange</code> у компоненті <code class=\"gatsby-code-text\">TemperatureInput</code> викликає <code class=\"gatsby-code-text\">this.props.onTemperatureChange()</code> з новим значенням. Його пропси, включно з <code class=\"gatsby-code-text\">onTemperatureChange</code>, були надані його батьківським компонентом <code class=\"gatsby-code-text\">Calculator</code>.</li>\n<li>Коли він раніше був відрендерений, <code class=\"gatsby-code-text\">Calculator</code> вказав, що <code class=\"gatsby-code-text\">onTemperatureChange</code> компонента <code class=\"gatsby-code-text\">TemperatureInput</code> за Цельсієм є методом <code class=\"gatsby-code-text\">handleCelsiusChange</code> компонента  <code class=\"gatsby-code-text\">Calculator</code>, а <code class=\"gatsby-code-text\">onTemperatureChange</code> компонента <code class=\"gatsby-code-text\">TemperatureInput</code> за Фаренгейтом є методом <code class=\"gatsby-code-text\">handleFahrenheitChange</code> компонента  <code class=\"gatsby-code-text\">Calculator</code>. Таким чином, будь-який з цих двох методів <code class=\"gatsby-code-text\">Calculator</code> викликається в залежності від того, яке поле вводу ми редагували.</li>\n<li>Усередині цих методів компонент <code class=\"gatsby-code-text\">Calculator</code> просить React повторно зробити рендер самого себе, шляхом виклику <code class=\"gatsby-code-text\">this.setState()</code> з новим введеним значенням і поточною шкалою вводу, яку ми щойно редагували.</li>\n<li>React викликає метод <code class=\"gatsby-code-text\">render</code> компонента<code class=\"gatsby-code-text\">Calculator</code>, щоб дізнатися, як повинен виглядати UI. Значення обох полів вводу перераховуються на основі поточної температури і шкали. Також тут відбувається перетворення температури.</li>\n<li>React викликає методи <code class=\"gatsby-code-text\">render</code> окремих компонентів <code class=\"gatsby-code-text\">TemperatureInput</code> з новими пропсами, визначеними <code class=\"gatsby-code-text\">Calculator</code>, і дізнається, як повинен виглядати їх UI.</li>\n<li>React викликає метод <code class=\"gatsby-code-text\">render</code> компонента <code class=\"gatsby-code-text\">BoilingVerdict</code>, передаючи температуру в градусах Цельсія в якості пропу.</li>\n<li>React DOM оновлює DOM відповідно до значень полів вводу. Поле, яке ми щойно редагували, отримує поточне значення, а інше - оновлюється до температури після перетворення.</li>\n</ul>\n<p>Кожне оновлення проходить ті ж кроки, щоб поля вводу залишалися синхронізованими.</p>\n<h2 id=\"lessons-learned\"><a href=\"#lessons-learned\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Засвоєні уроки </h2>\n<p>Необхідно створити єдине “джерело істини” для будь-яких даних, які змінюються у додатку React. Зазвичай стан спочатку додають до компонента, який його потребує для рендеринга. Потім, якщо інші компоненти також потребують цього стану, ви можете підняти його до їхнього найближчого спільного предка. Замість того, щоб намагатися синхронізувати стан між різними компонентами, слід покладатися на <a href=\"/docs/state-and-lifecycle.html#the-data-flows-down\">потік даних вниз</a>.</p>\n<p>Підйом стану передбачає написання більше “шаблонного” коду, ніж при підході з двосторонньою прив’язкою даних. В результаті це надасть нам певні переваги - щоб знайти і ізолювати помилки потрібно буде затратити менше часу. Оскільки будь-який стан “живе” в певному компоненті і сам компонент може його змінити, область пошуку помилок значно зменшується. Крім того, ви можете реалізувати будь-яку користувацьку логіку, щоб відхилити або перетворити дані, введені користувачем.</p>\n<p>Якщо щось може бути обчислено або з пропсів, або з стану, це, ймовірно, не повинно бути в стані. Наприклад, замість того, щоб зберігати і <code class=\"gatsby-code-text\">celsiusValue</code>, і <code class=\"gatsby-code-text\">fahrenheitValue</code>, ми зберігаємо тільки останню редаговану <code class=\"gatsby-code-text\">temperature</code> і її <code class=\"gatsby-code-text\">scale</code>. Значення інших вхідних даних завжди може бути обчислено на їх основі у методі <code class=\"gatsby-code-text\">render()</code>. Це дозволяє очистити або застосувати округлення до іншого поля без втрати будь-якої точності введених даних користувачем.</p>\n<p>Коли ви бачите якусь помилку в UI, ви можете скористатися <a href=\"https://github.com/facebook/react/tree/master/packages/react-devtools\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">React Developer Tools</a> для перевірки пропсів і переміщуватися вгору по дереву, поки не знайдете компонент, відповідальний за оновлення стану. Це дозволяє відслідковувати джерело помилок:</p>\n<img src=\"/ef94afc3447d75cdc245c77efb0d63be/react-devtools-state.gif\" alt=\"&#x41A;&#x43E;&#x43D;&#x442;&#x440;&#x43E;&#x43B;&#x44C; &#x441;&#x442;&#x430;&#x43D;&#x443; &#x432; React DevTools\" max-width=\"100%\" height=\"100%\">","frontmatter":{"title":"Підйом стану","next":"composition-vs-inheritance.html","prev":"forms.html"},"fields":{"path":"content/docs/lifting-state-up.md","slug":"docs/lifting-state-up.html"}}},"pageContext":{"slug":"docs/lifting-state-up.html"}},"staticQueryHashes":[]}