{"componentChunkName":"component---src-templates-docs-js","path":"/docs/thinking-in-react.html","result":{"data":{"markdownRemark":{"html":"<p>З нашої точки зору, React — це відмінний спосіб писати великі і швидкі JavaScript-додатки. Він дуже добре масштабувався для нас у Facebook та Instagram.</p>\n<p>Одна з особливостей React – це те, як він змушує думати про додатки в процесі їх створення. У цьому документі ми покажемо хід думок для створення таблиці продуктів з пошуком за допомогою React.</p>\n<h2 id=\"start-with-a-mock\"><a href=\"#start-with-a-mock\" 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>Уявіть, що у нас вже є JSON API і макет дизайну сайту. Він виглядає так:</p>\n<p>\n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 228px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 121.42857142857144%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAIAAAB1KUohAAAACXBIWXMAABYlAAAWJQFJUiTwAAACZUlEQVQ4y4VU23KqQBD0/z8nL0bjJeId8aggctOggmDQIypKFIVNy6ZSpiKkH6aWWXpnenZmM4SQKIqud7g8AvzkFzJguq673+89z4M9HA4fP+H7Pix2f/Nv5OVyaRgG7Gq12m635BFOpxPiPyDjbHAcx/FibDYb2OPxCLvb7fYx8APiB0GAU7CgWdzI2EPker3e6XQURanVao1GAwt42u02bKvVYllWVVWe5yuVCn5AmjcyLRhNA+dhHYYh9VALZxgjivG9+CLLsowjNU2zbZt6kSSyGI/Hi8WCJONGFkUxm81yHIdUqRdCms3mYDDA1h9kRNB1HWGhSo8hCAKCT6dTOO91PSAj51wu1+v1EKdYLHa7XeSMT9RpOBz+QZ7NZvP5HDl/i8QNgTaZTHAc1fKQn6HlAR85j0Yjmic04yA4kblpmmlk1FkUhImmqYoiiSKaAJFRP/ghHneTVjDTtkfTqWIYqmFopnmNew5MSICcJMFfZNLpkNdX0mwShokYBva/rrc5TpYk3Ba0pKVNLIugqiiMphH8qmmnw+FN1y3LgmBMSxq5VK0+vbxUOS7PMBWWLaM/Wq0UqT/IK8cxZjPn/d00DKzXjmNbFgbwvs+T21OS+jyvyvIYZRdFSZZHolgoFDBStEnT0j5igm17vdt9XC62aTrLJd4WCMaEr9drrFOrXauR52dSKKDmEcsSz1u5bpVhELzf76Nhkzr8Rg48L/R94rrRdntGnOv1fD7TmHhM0H94QBIjC5iHUukfz/eHw3nc23go0GHlchkTks/nISExMkrqx8DjRL3wBDHOMZKu7ROsMUWkc+uRSQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"Макет\"\n        title=\"\"\n        src=\"/static/1071fbcc9eed01fddc115b41e193ec11/d4770/thinking-in-react-mock.png\"\n        srcset=\"/static/1071fbcc9eed01fddc115b41e193ec11/65ed1/thinking-in-react-mock.png 210w,\n/static/1071fbcc9eed01fddc115b41e193ec11/d4770/thinking-in-react-mock.png 228w\"\n        sizes=\"(max-width: 228px) 100vw, 228px\"\n      />\n    </span>\n  </span>\n  </p>\n<p>Наш JSON API повертає дані, які виглядають наступним чином:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"gatsby-code-text\"><code class=\"gatsby-code-text\">[\n  {category: &quot;Sporting Goods&quot;, price: &quot;$49.99&quot;, stocked: true, name: &quot;Football&quot;},\n  {category: &quot;Sporting Goods&quot;, price: &quot;$9.99&quot;, stocked: true, name: &quot;Baseball&quot;},\n  {category: &quot;Sporting Goods&quot;, price: &quot;$29.99&quot;, stocked: false, name: &quot;Basketball&quot;},\n  {category: &quot;Electronics&quot;, price: &quot;$99.99&quot;, stocked: true, name: &quot;iPod Touch&quot;},\n  {category: &quot;Electronics&quot;, price: &quot;$399.99&quot;, stocked: false, name: &quot;iPhone 5&quot;},\n  {category: &quot;Electronics&quot;, price: &quot;$199.99&quot;, stocked: true, name: &quot;Nexus 7&quot;}\n];</code></pre></div>\n<h2 id=\"step-1-break-the-ui-into-a-component-hierarchy\"><a href=\"#step-1-break-the-ui-into-a-component-hierarchy\" 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>Крок 1: Розіб’ємо інтерфейс на компоненти </h2>\n<p>Перше, що треба зробити – це уявити кордони кожного компонента (і підкомпонента) в макеті та дати їм імена. Якщо ви працюєте з дизайнерами, цілком можливо, що вони вже якось називають компоненти – вам варто поспілкуватися! Наприклад, шари Photoshop часто підказують імена для React-компонентів.</p>\n<p>Але як вибрати, що є компонентом, а що ні? Це схоже на те, як ви вирішуєте, чи треба оголосити функцію або об’єкт. Можна застосувати <a href=\"https://uk.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D1%94%D0%B4%D0%B8%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BE%D0%B1%D0%BE%D0%B2&#x27;%D1%8F%D0%B7%D0%BA%D1%83\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">принцип єдиного обов’язку</a>: кожний компонент в ідеалі повинен займатися якимось одним завданням. Якщо функціонал компонента збільшується з плином часу, його слід розбити на більш дрібні підкомпоненти.</p>\n<p>Багато інтерфейсів показують модель даних JSON. Тому добре побудована модель, як правило, вже відображає призначений для користувача інтерфейс (а значить, і структуру компонентів). Інтерфейс і моделі даних часто мають схожу <em>інформаційну архітектуру</em>, тому розділити інтерфейс на частини не складає труднощів. Розбийте інтерфейс користувача на компоненти, кожен з яких відображає частину моделі даних.</p>\n<p>\n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 275px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 116.1904761904762%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAXCAIAAACEf/j0AAAACXBIWXMAABYlAAAWJQFJUiTwAAADjklEQVQ4y32UaXOjOBCG5///mZ1PM9lsbMcXvsExxge+MPbY5pIQCCTOHuFM1klt1cKDqqXiVR+0+AbiKjOArBr/H/hEtVJ+ExanxHY5wsxDAl6B/wPirscEnscsh0dBCGVSiUnAAlomacqTjPH0K4kgZkmS5kUJeVEFyhJAfgLAKzENE+Szk2k4tm1ZtzAMREhlUYgH7pYg4bzKr6zEPAWffIiDkAVRTikRSoyRT3xBFFGxizACMfo4pCHj7D5GX8WEB0FBkD9T1KW2Xi30N0VdLzf6aiuPp8KeyjPzcNrqe3mkLLUlpYXvp+/iHNNAtbDuoSONtz7Z+sE+CNcu2mBi0Ggf0ENA9yQUi8IwQrpwA4dQAFGwIsMgwr39ePnRkBraei6yyiEfKP1a+0VdzzLIWMk48ARE3iLkhAL1CwfyTIhzr7idGB9t9ur5Mt4d9pjojreynOnxpNseAUBliQHeEdMzpG7uQpFWnhHYS4S+//wpyZO61H1qNBqSJIznVlNeaGGWeVGE4ljgxTGJ2C6hTuFCnv7x7J+OW13X5uqbolzOZyiL2VRZzOfyZHzY79KEi9rHEY2jkMUscH/h5Ca8Vp7d0mJb/VenZXZam3+ePWUCp+NRTLtto9WM9RVcznA2Pzjxo45S648YgYU360G9pvZ743ZTHQ4gIItOW2s114MeEB8cG1znjg2exy+Hh9gBu1gt4O8naDag9gLPTzAZHXqS0Zd2nbanzYW4vF7gdr1j8fPuIXbBIsbBrddCqRv0pLDVpOvV21xV3qbyVDHMYxhRLNouEO3mkzB0vcvnsO05xs/dbn04bIxGjfH4ddC3bLtqZtEKWUY5i0TNEk4TLu5DHtuPape3m3XtjwZjeSLP3maaJquzvjyZLjRFm+/OJxRRJyBuGAi8kF59C2X2u2chtuLDbtXr7qeypa+XUvesyGq9tm63Vq1XZ70EJF65gW2BfQPHuef88amc0ioOO/j+F7w2oPkK4xFgbzMaKvWaPuhrnVZqXQEjsQUgFzBm1+OXgiWbVSR1smEv7UvRsAemcei09NeaIbWNbis/7uF8/MDk5uM7VzlT8yj3B7OJvFksieuJU7CdqauJshxPFuOJOPHVuRCnI2bAM+5eUdVheSW28wtiN983PWwgZPjkhH0T+SYmJ/RufIJgU7jycvtebfG/SQkvHjAxlkFl5J/Wxcq/FKTIiPiB/gZ6RfG+cqwoSwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"Діаграма компонентів\"\n        title=\"\"\n        src=\"/static/eb8bda25806a89ebdc838813bdfa3601/6b2ea/thinking-in-react-components.png\"\n        srcset=\"/static/eb8bda25806a89ebdc838813bdfa3601/65ed1/thinking-in-react-components.png 210w,\n/static/eb8bda25806a89ebdc838813bdfa3601/6b2ea/thinking-in-react-components.png 275w\"\n        sizes=\"(max-width: 275px) 100vw, 275px\"\n      />\n    </span>\n  </span>\n  </p>\n<p>Ви побачите, що ми маємо п’ять компонентів у нашому додатку. Дані, які представляє кожен компонент, виділено курсивом.</p>\n<ol>\n<li><strong><code class=\"gatsby-code-text\">FilterableProductTable</code> (помаранчевий):</strong> містить весь приклад</li>\n<li><strong><code class=\"gatsby-code-text\">SearchBar</code> (синій):</strong> приймає всі <em>вхідні дані користувача</em></li>\n<li><strong><code class=\"gatsby-code-text\">ProductTable</code> (зелений):</strong> відображає та фільтрує <em>збір даних</em> на основі <em>вхідних даних користувача</em></li>\n<li><strong><code class=\"gatsby-code-text\">ProductCategoryRow</code> (бірюзовий):</strong> відображає заголовок для кожної <em>категорії</em></li>\n<li><strong><code class=\"gatsby-code-text\">ProductRow</code> (червоний):</strong> відображає рядок для кожного <em>продукту</em></li>\n</ol>\n<p>Зверніть увагу, що заголовок таблиці всередині <code class=\"gatsby-code-text\">ProductTable</code> не є окремим компонентом. Відокремлювати його чи ні — це питання особистих уподобань. У цьому прикладі ми залишили його як частину <code class=\"gatsby-code-text\">ProductTable</code>, оскільки він є малою частиною загального <em>збору даних</em>. Проте, якщо в майбутньому заголовок поповниться новими функціями (наприклад, можливістю сортувати товар), є сенс витягти його в самостійний компонент <code class=\"gatsby-code-text\">ProductTableHeader</code>.</p>\n<p>Тепер, коли ми визначили компоненти в нашому макеті, давайте розташуємо їх в порядку підпорядкованості. Компоненти, які є частиною інших компонентів, в ієрархії відображаються як дочірні:</p>\n<ul>\n<li>\n<p><code class=\"gatsby-code-text\">FilterableProductTable</code></p>\n<ul>\n<li><code class=\"gatsby-code-text\">SearchBar</code></li>\n<li>\n<p><code class=\"gatsby-code-text\">ProductTable</code></p>\n<ul>\n<li><code class=\"gatsby-code-text\">ProductCategoryRow</code></li>\n<li><code class=\"gatsby-code-text\">ProductRow</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"step-2-build-a-static-version-in-react\"><a href=\"#step-2-build-a-static-version-in-react\" 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>Крок 2: Побудуємо статичну версію в React </h2>\n<p data-height=\"600\" data-theme-id=\"0\" data-slug-hash=\"BwWzwm\" data-default-tab=\"js\" data-user=\"lacker\" data-embed-version=\"2\" class=\"codepen\">Приклад коду <a href=\"https://codepen.io/gaearon/pen/BwWzwm\">Філософія React: Крок 2</a> на <a href=\"https://codepen.io\">CodePen</a>.</p>\n<script async src=\"https://production-assets.codepen.io/assets/embed/ei.js\"></script>\n<p>Тепер, коли всі компоненти розташовані в ієрархічному порядку, прийшов час реалізувати наш додаток. Найлегший спосіб – створити версію, яка використовує модель даних і рендерить інтерфейс, але не передбачає ніякої інтерактивності. Корисно розділяти ці процеси, тому що написання статичної версії вимагає багато друкування і зовсім небагато мислення. З іншого боку, створення інтерактивності в додатку передбачає більш глибокий розумовий процес і лише частку рутинного друку. Ми розберемося, чому так виходить.</p>\n<p>Щоб побудувати статичну версію додатка, яка буде показувати модель даних, нам потрібно створити компоненти, які використовують інші компоненти і передають дані через <em>пропси</em>. <em>Пропси</em> — це спосіб передачі даних від батьків до дочірних елементів. Якщо ви знайомі з поняттям <em>стану</em>, то для статичної версії це якраз те, що вам <strong>використовувати не потрібно</strong>. Стан передбачає собою дані, які змінюються з часом – інтерактивність. Так як ми працюємо над статичною версією додатка, то нам це не потрібно.</p>\n<p>Написання коду можна почати як зверху вниз (з великого <code class=\"gatsby-code-text\">FilterableProductTable</code>), так і знизу до верху (з маленького <code class=\"gatsby-code-text\">ProductRow</code>). Простіші додатки зручніше починати з компонентів, що знаходяться вище за ієрархією. У більш складних додатках зручніше в першу чергу створювати і тестувати підкомпоненти.</p>\n<p>Наприкінці цього кроку ви матимете бібліотеку компонентів, які можуть бути використані повторно. Так як це статична версія, то компоненти матимуть тільки методи <code class=\"gatsby-code-text\">render()</code>. Компонент вище за ієрархією (<code class=\"gatsby-code-text\">FilterableProductTable</code>) буде передавати модель даних через пропси. Якщо ви внесете зміни в базову модель даних і знову викличите <code class=\"gatsby-code-text\">ReactDOM.render()</code>, то побачите зміни в інтерфейсі. Немає нічого складного у відстеженні змін та оновленні інтерфейсу. Завдяки <strong>односторонньому потоку даних</strong> (або <em>односторонній прив’язці</em>) код працює швидко, але залишається зрозумілим.</p>\n<p>Якщо у вас залишилися запитання щодо виконання цього кроку, зверніться до <a href=\"/docs/\">документації React</a>.</p>\n<h3 id=\"a-brief-interlude-props-vs-state\"><a href=\"#a-brief-interlude-props-vs-state\" 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>Невеликий відступ: як пропси відрізняються від стану </h3>\n<p>Існує два типи “моделі” даних у React: пропси та стан. Важливо, щоб ви розуміли різницю між ними, в іншому випадку зверніться до <a href=\"/docs/state-and-lifecycle.html\">офіційної документації React</a>. Також див. <a href=\"/docs/faq-state.html#what-is-the-difference-between-state-and-props\">FAQ: У чому полягає різниця між state та props?</a></p>\n<h2 id=\"step-3-identify-the-minimal-but-complete-representation-of-ui-state\"><a href=\"#step-3-identify-the-minimal-but-complete-representation-of-ui-state\" 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>Крок 3: Визначимо мінімальне (але повноцінне) відображення стану інтерфейсу </h2>\n<p>Щоб зробити інтерфейс користувача інтерактивним, потрібно, щоб модель даних могла змінюватися з часом. У React це можливо за допомогою <strong>стану</strong>.</p>\n<p>Щоб правильно побудувати додаток, спочатку потрібно подумати про мінімальний набір змінних станів, які потрібні вашому додатку. Головне тут дотримуватися принципу розробки <a href=\"https://uk.wikipedia.org/wiki/Don%27t_repeat_yourself\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">DRY: <em>Don’t Repeat Yourself</em> (укр. не повторюй себе)</a>. Визначте мінімальну кількість необхідного стану, який потрібен вашому додатку, все інше обчислюйте за необхідності. Наприклад, якщо ви створюєте список справ, тримайте масив пунктів списку під рукою – але не варто зберігати окремий стан для кількості справ у списку. Якщо треба відобразити кількість елементів, просто використовуйте довжину існуючого масиву.</p>\n<p>Давайте перелічимо всі дані у нашому додатку. Ми маємо:</p>\n<ul>\n<li>Початковий список товарів</li>\n<li>Пошуковий запит, введений користувачем</li>\n<li>Значення прапорця</li>\n<li>Відфільтрований список товарів</li>\n</ul>\n<p>Давайте розглянемо кожну частину даних і визначимо, яка з них є станом. Задайте собі наступні три питання:</p>\n<ol>\n<li>Передається вона від батька через пропси? Якщо так, тоді, напевно, це не стан.</li>\n<li>Залишається вона незмінною з часом? Якщо так, тоді, напевно, це не стан.</li>\n<li>Чи можете ви обчислити її на основі будь-якої іншої частини стану або пропсів у своєму компоненті? Якщо так, тоді, напевно, це не стан.</li>\n</ol>\n<p>Початковий список товарів передається через пропси, так що станом він бути не може. Пошуковий запит і прапорець змінюються з часом, також їх не можна обчислити з інших даних, тому вони цілком можуть бути станом. Наостанок, відфільтрований список товарів не є станом, так як його можна обчислити з оригінального списку, пошукового запиту та значення прапорця.</p>\n<p>У підсумку, наш стан виглядатиме наступним чином:</p>\n<ul>\n<li>Пошуковий запит</li>\n<li>Значення прапорця</li>\n</ul>\n<h2 id=\"step-4-identify-where-your-state-should-live\"><a href=\"#step-4-identify-where-your-state-should-live\" 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>Крок 4: Визначимо, де має перебувати наш стан </h2>\n<p data-height=\"600\" data-theme-id=\"0\" data-slug-hash=\"qPrNQZ\" data-default-tab=\"js\" data-user=\"lacker\" data-embed-version=\"2\" class=\"codepen\">Приклад коду <a href=\"https://codepen.io/gaearon/pen/qPrNQZ\">Філософія React: Крок 4</a> на <a href=\"https://codepen.io\">CodePen</a>.</p>\n<p>Отже, ми визначили мінімальний набір станів додатку. Далі нам потрібно з’ясувати, який з компонентів <em>володіє</em> станом або змінює його.</p>\n<p>Пам’ятайте: у React односторонній потік даних, який сходить згори вниз в ієрархічному порядку. Спочатку може бути не зовсім зрозуміло, який з компонентів повинен володіти яким станом. <strong>На цьому етапі новачки спотикаються найчастіше,</strong> тому дотримуйтеся цих вказівок, щоб розібратися:</p>\n<p>Для кожної частини стану в додатку:</p>\n<ul>\n<li>Визначте компоненти, які рендерять щось на основі цього стану.</li>\n<li>Знайдіть спільний батьківський компонент (компонент, розташований над іншими компонентами, яким потрібен цей стан).</li>\n<li>Або спільний батьківський компонент, або будь-який компонент, що стоїть вище за ієрархією, повинен містити стан.</li>\n<li>Якщо вам не вдається знайти відповідний компонент, створіть один виключно для стану та розмістить його вище за ієрархією над загальним спільним батьківським компонентом.</li>\n</ul>\n<p>Давайте застосуємо цю стратегію на прикладі нашого додатку:</p>\n<ul>\n<li>Завдання <code class=\"gatsby-code-text\">ProductTable</code> – відфільтрувати список товарів, базуючись на стані, а завдання <code class=\"gatsby-code-text\">SearchBar</code> – відобразити стан для пошукового запиту та прапорця.</li>\n<li>Спільний батьківський компонент для обох – <code class=\"gatsby-code-text\">FilterableProductTable</code>.</li>\n<li>Згідно ідеї, є сенс помістити текст фільтра та значення прапорця в  <code class=\"gatsby-code-text\">FilterableProductTable</code></li>\n</ul>\n<p>Отже, ми вирішили розташувати наш стан у <code class=\"gatsby-code-text\">FilterableProductTable</code>. Перше, що потрібно зробити - додати властивість <code class=\"gatsby-code-text\">this.state = {filterText: &#39;&#39;, inStockOnly: false}</code> до конструктора <code class=\"gatsby-code-text\">FilterableProductTable</code>, щоб відобразити початковий стан додатку. Після цього, передайте <code class=\"gatsby-code-text\">filterText</code> та <code class=\"gatsby-code-text\">inStockOnly</code> до <code class=\"gatsby-code-text\">ProductTable</code> і <code class=\"gatsby-code-text\">SearchBar</code> через пропси. Нарешті, використайте пропси для фільтрації рядків у <code class=\"gatsby-code-text\">ProductTable</code> і визначення значень полів форми <code class=\"gatsby-code-text\">SearchBar</code>.</p>\n<p>Ви помітите зміни у поведінці вашого додатку: задайте значення <code class=\"gatsby-code-text\">&quot;ball&quot;</code> для <code class=\"gatsby-code-text\">filterText</code> та оновіть сторінку. Ви побачите відповідні зміни в таблиці даних.</p>\n<h2 id=\"step-5-add-inverse-data-flow\"><a href=\"#step-5-add-inverse-data-flow\" 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>Крок 5: Додамо зворотний потік даних </h2>\n<p data-height=\"600\" data-theme-id=\"0\" data-slug-hash=\"LzWZvb\" data-default-tab=\"js,result\" data-user=\"rohan10\" data-embed-version=\"2\" data-pen-title=\"Thinking In React: Step 5\" class=\"codepen\">Приклад коду <a href=\"https://codepen.io/gaearon/pen/LzWZvb\">Філософія React: Крок 5</a> на <a href=\"https://codepen.io\">CodePen</a>.</p>\n<p>Поки що наш додаток рендериться в залежності від пропсів і стану, що передаються вниз по ієрархії. Тепер ми забезпечимо потік даних у зворотний бік: наше завдання зробити так, щоб компоненти форми у самому низу ієрархії оновлювали стан у <code class=\"gatsby-code-text\">FilterableProductTable</code>.</p>\n<p>Потік даних у React - односторонній. Це допомагає зрозуміти, як працює додаток, але нам потрібно трохи більше коду, ніж в традиційній двосторонній прив’язці даних.</p>\n<p>Якщо ви спробуєте ввести текст у поле пошуку або встановити прапорець в даній версії прикладу, то побачите, що React ігнорує будь-яке введення. Це навмисне, так як раніше ми прирівняли значення пропа <code class=\"gatsby-code-text\">value</code> в <code class=\"gatsby-code-text\">input</code> до <code class=\"gatsby-code-text\">state</code> в <code class=\"gatsby-code-text\">FilterableProductTable</code>.</p>\n<p>Давайте поміркуємо, як ми хочемо змінити поведінку. Нам потрібно, щоб при змінах пошукової форми змінювався стан введення. Так як компоненти повинні оновлювати тільки той стан, що належить їм, <code class=\"gatsby-code-text\">FilterableProductTable</code> передасть функцію зворотнього виклику у <code class=\"gatsby-code-text\">SearchBar</code>. У свою чергу, <code class=\"gatsby-code-text\">SearchBar</code> викликатиме цю функцію зворотнього виклику кожен раз, коли треба оновити стан. Щоб отримувати повідомлення про зміни елементів форми, ми можемо використовувати подію <code class=\"gatsby-code-text\">onChange</code>. Функції зворотнього виклику, передані з <code class=\"gatsby-code-text\">FilterableProductTable</code> викличуть <code class=\"gatsby-code-text\">setState()</code>, і додаток оновиться.</p>\n<p>Бодай звучить складно, але це займає всього кілька рядків коду. А головне, потік даних через додаток залишається прямим і зрозумілим.</p>\n<h2 id=\"and-thats-it\"><a href=\"#and-thats-it\" 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. Хоча цей процес і використовує трохи більше коду, пам’ятайте: код читають частіше, ніж пишуть. А такий модульний та прямий код, як в нашому додатку, читається не так складно. Коли ви почнете створювати великі бібліотеки компонентів, ви зможете по-справжньому оцінити прямолінійність і зв’язаність React, а повторно використовувані компоненти зроблять ваш код набагато коротшим. :)</p>","frontmatter":{"title":"Філософія React","next":null,"prev":"composition-vs-inheritance.html"},"fields":{"path":"content/docs/thinking-in-react.md","slug":"docs/thinking-in-react.html"}}},"pageContext":{"slug":"docs/thinking-in-react.html"}},"staticQueryHashes":[]}