diff --git a/src/content/learn/preserving-and-resetting-state.md b/src/content/learn/preserving-and-resetting-state.md
index d35071845..67b142996 100644
--- a/src/content/learn/preserving-and-resetting-state.md
+++ b/src/content/learn/preserving-and-resetting-state.md
@@ -1,28 +1,28 @@
---
-title: Preserving and Resetting State
+title: Збереження та скидання стану
---
-State is isolated between components. React keeps track of which state belongs to which component based on their place in the UI tree. You can control when to preserve state and when to reset it between re-renders.
+Стан ізольований між компонентами. React відстежує, який стан належить якому компоненту, виходячи з їх місця в дереві інтерфейсу користувача. Ви можете керувати тим, коли зберігати стан, а коли скидати його між рендерами.
-* When React chooses to preserve or reset the state
-* How to force React to reset component's state
-* How keys and types affect whether the state is preserved
+* Коли React зберігає або скидає стан
+* Як примусити React скинути стан компоненти
+* Як ключі та типи впливають на збереження стану
-## State is tied to a position in the render tree {/*state-is-tied-to-a-position-in-the-tree*/}
+## Стан прив'язаний до позиції у дереві рендерингу {/*state-is-tied-to-a-position-in-the-tree*/}
-React builds [render trees](learn/understanding-your-ui-as-a-tree#the-render-tree) for the component structure in your UI.
+React будує [дерева рендерингу](learn/understanding-your-ui-as-a-tree#the-render-tree) для структури компонентів у вашому інтерфейсі.
-When you give a component state, you might think the state "lives" inside the component. But the state is actually held inside React. React associates each piece of state it's holding with the correct component by where that component sits in the render tree.
+Коли ви надаєте компоненту стан, ви можете подумати, що стан "живе" всередині компонента. Але насправді стан зберігається всередині React. React пов'язує кожен фрагмент стану, який він утримує, з відповідним компонентом, по тому де цей компонент знаходиться в дереві рендерингу.
-Here, there is only one `` JSX tag, but it's rendered at two different positions:
+В даному прикладі використовується тільки один JSX тег ``, але він рендериться в двох різних позиціях.
@@ -56,7 +56,7 @@ function Counter() {
>
{score}
);
@@ -70,7 +70,7 @@ label {
}
.counter {
- width: 100px;
+ width: 150px;
text-align: center;
border: 1px solid gray;
border-radius: 4px;
@@ -86,23 +86,23 @@ label {
-Here's how these look as a tree:
+Ось як вони відображаються у вигляді дерева:
-
+
-React tree
+React дерево
-**These are two separate counters because each is rendered at its own position in the tree.** You don't usually have to think about these positions to use React, but it can be useful to understand how it works.
+**Це два окремі лічильника, оскільки кожен із них рендериться на своїй позиції в дереві.** Зазвичай вам не потрібно думати про ці позиції щоб використовувати React, але розуміння того, як це працює, може бути корисним.
-In React, each component on the screen has fully isolated state. For example, if you render two `Counter` components side by side, each of them will get its own, independent, `score` and `hover` states.
+В React, кожен компонент на екрані має повністю ізольований стан. Для прикладу, якщо ви рендерите два компоненти `Counter` поруч, кожен з них отримає свої власні, незалежні стани `score` та `hover`.
-Try clicking both counters and notice they don't affect each other:
+Спробуйте натиснути на обидва лічильника і ви помітите, що вони не впливають один на одного:
@@ -135,7 +135,7 @@ function Counter() {
>
{score}
);
@@ -144,7 +144,7 @@ function Counter() {
```css
.counter {
- width: 100px;
+ width: 150px;
text-align: center;
border: 1px solid gray;
border-radius: 4px;
@@ -160,21 +160,21 @@ function Counter() {
-As you can see, when one counter is updated, only the state for that component is updated:
+Як ви можете бачити, коли один лічильник оновлюється, тільки стан тієї компоненти оновлюється:
-
+
-Updating state
+Оновлення стану
-React will keep the state around for as long as you render the same component at the same position in the tree. To see this, increment both counters, then remove the second component by unchecking "Render the second counter" checkbox, and then add it back by ticking it again:
+React зберігатиме цей стан доти, доки ви рендерите той самий компонент у тій самій позиції в дереві. Щоб побачити це, збільште обидва лічильника, потім видаліть другий компонент, знявши галочку "Рендерити другий лічильник", а потім додайте його назад, поставивши галочку знову:
@@ -195,7 +195,7 @@ export default function App() {
setShowB(e.target.checked)
}}
/>
- Render the second counter
+ Рендерити другий лічильник
);
@@ -218,7 +218,7 @@ function Counter() {
>
{score}
);
@@ -232,7 +232,7 @@ label {
}
.counter {
- width: 100px;
+ width: 150px;
text-align: center;
border: 1px solid gray;
border-radius: 4px;
@@ -248,35 +248,35 @@ label {
-Notice how the moment you stop rendering the second counter, its state disappears completely. That's because when React removes a component, it destroys its state.
+Зверніть увагу, що як тільки ви зупиняєте рендеринг другого лічильника, його стан повністю зникає. Це тому, що коли React видаляє компонент, він знищує його стан.
-
+
-Deleting a component
+Видалення компонента
-When you tick "Render the second counter", a second `Counter` and its state are initialized from scratch (`score = 0`) and added to the DOM.
+Коли ви вибираєте "Рендерити другий лічильник", другий `Counter` і його стан ініціалізуються з нуля (`рахунок = 0`) і додаються до DOM.
-
+
-Adding a component
+Додавання компонента
-**React preserves a component's state for as long as it's being rendered at its position in the UI tree.** If it gets removed, or a different component gets rendered at the same position, React discards its state.
+**React зберігає стан компоненти до тих пір, поки компонент рендериться на своєму місці в дереві інтерфейсу користувача.** Якщо його буде видалено, або на тому ж місці буде відрендерено інший компонент, React очистить його стейт.
-## Same component at the same position preserves state {/*same-component-at-the-same-position-preserves-state*/}
+## Той самий компонент у тій самій позиції зберігає стан {/*same-component-at-the-same-position-preserves-state*/}
-In this example, there are two different `` tags:
+У цьому прикладі є два різних `` теги:
@@ -300,7 +300,7 @@ export default function App() {
setIsFancy(e.target.checked)
}}
/>
- Use fancy styling
+ Використати вишукану стилізацію
);
@@ -326,7 +326,7 @@ function Counter({ isFancy }) {
>
{score}
);
@@ -340,7 +340,7 @@ label {
}
.counter {
- width: 100px;
+ width: 150px;
text-align: center;
border: 1px solid gray;
border-radius: 4px;
@@ -361,24 +361,24 @@ label {
-When you tick or clear the checkbox, the counter state does not get reset. Whether `isFancy` is `true` or `false`, you always have a `` as the first child of the `div` returned from the root `App` component:
+Коли ви встановлюєте або знімаєте прапорець, стан лічильника не обнуляється. Не залежно від того, чи `isFancy` є `true` або `false`, у вас завжди є `` як перший дочірній елемент `div`, що повертається з кореневого компонента `App`.
-
+
-Updating the `App` state does not reset the `Counter` because `Counter` stays in the same position
+Оновлення стану `App` не обнуляє `Counter`, оскільки `Counter` залишається на тій самій позиції
-It's the same component at the same position, so from React's perspective, it's the same counter.
+Це той самий компонент на тій самій позиції, отже з точки зору React, це той самий лічильник.
-Remember that **it's the position in the UI tree--not in the JSX markup--that matters to React!** This component has two `return` clauses with different `` JSX tags inside and outside the `if`:
+Пам'ятайте, що **це позиція в дереві інтерфейсу користувача — не в JSX-розмітці — для React це важливо!** Цей компонент має два `return` пункти з різними `` JSX-тегами в середині та зовні `if`:
@@ -399,7 +399,7 @@ export default function App() {
setIsFancy(e.target.checked)
}}
/>
- Use fancy styling
+ Використати вишукану стилізацію
);
@@ -415,7 +415,7 @@ export default function App() {
setIsFancy(e.target.checked)
}}
/>
- Use fancy styling
+ Використати вишукану стилізацію
);
@@ -441,7 +441,7 @@ function Counter({ isFancy }) {
>
{score}
);
@@ -455,7 +455,7 @@ label {
}
.counter {
- width: 100px;
+ width: 150px;
text-align: center;
border: 1px solid gray;
border-radius: 4px;
@@ -476,15 +476,15 @@ label {
-You might expect the state to reset when you tick checkbox, but it doesn't! This is because **both of these `` tags are rendered at the same position.** React doesn't know where you place the conditions in your function. All it "sees" is the tree you return.
+Ви можете очікувати, що стан буде обнулено, коли ви поставите галочку, але цього не станеться! Це тому, що **обидва теги `` рендеряться на тій самій позиції.** React не знає, де ви розміщуєте умови у вашій функції. Все, що він "бачить" — це дерево, що ви повертаєте.
-In both cases, the `App` component returns a `
` with `` as a first child. To React, these two counters have the same "address": the first child of the first child of the root. This is how React matches them up between the previous and next renders, regardless of how you structure your logic.
+В обох випадках, `App` компонент повертає `
` із `` як першим дочірнім елементом. Для React ці два лічильника мають однакову "адресу": перший нащадок першого нащадка кореня. Ось як React зіставляє їх між попереднім і наступним рендерингом, незалежно від того, як ви структуруєте свою логіку.
-## Different components at the same position reset state {/*different-components-at-the-same-position-reset-state*/}
+## Різні компоненти на тій самій позиції скидають стан {/*different-components-at-the-same-position-reset-state*/}
-In this example, ticking the checkbox will replace `` with a `
`:
+В цьому прикладі встановлення прапорця замінить `` на `
) : (
)}
@@ -508,7 +508,7 @@ export default function App() {
setIsPaused(e.target.checked)
}}
/>
- Take a break
+ Зробіть перерву
);
@@ -531,7 +531,7 @@ function Counter() {
>
{score}
);
@@ -545,7 +545,7 @@ label {
}
.counter {
- width: 100px;
+ width: 150px;
text-align: center;
border: 1px solid gray;
border-radius: 4px;
@@ -561,13 +561,13 @@ label {
-Here, you switch between _different_ component types at the same position. Initially, the first child of the `
` contained a `Counter`. But when you swapped in a `p`, React removed the `Counter` from the UI tree and destroyed its state.
+Тут, ви переключаєте між _різними_ типами компонент на одній позиції. Початково перший дочірній елемент `
` містив `Counter`. Але коли ви замінили його на `p`, React видалив `Counter` з дерева інтерфейсу та знищив його стан.
-
+
-When `Counter` changes to `p`, the `Counter` is deleted and the `p` is added
+Коли `Counter` змінюється на `p`, то `Counter` видалено та `p` добавлено
@@ -575,15 +575,15 @@ When `Counter` changes to `p`, the `Counter` is deleted and the `p` is added
-
+
-When switching back, the `p` is deleted and the `Counter` is added
+Коли перемикаємо назад, `p` видалено та `Counter` додано
-Also, **when you render a different component in the same position, it resets the state of its entire subtree.** To see how this works, increment the counter and then tick the checkbox:
+Крім того, **коли ви рендерите інший компонент у тому самому місці, це скидає стан усього його піддерева.** Щоб побачити, як це працює, збільште лічильник і потім встановіть прапорець:
@@ -611,7 +611,7 @@ export default function App() {
setIsFancy(e.target.checked)
}}
/>
- Use fancy styling
+ Використати вишукану стилізацію
);
@@ -651,7 +651,7 @@ label {
}
.counter {
- width: 100px;
+ width: 150px;
text-align: center;
border: 1px solid gray;
border-radius: 4px;
@@ -672,13 +672,13 @@ label {
-The counter state gets reset when you click the checkbox. Although you render a `Counter`, the first child of the `div` changes from a `div` to a `section`. When the child `div` was removed from the DOM, the whole tree below it (including the `Counter` and its state) was destroyed as well.
+Стан лічильника скидається коли ви натискаєте на прапорець. Хоча ви рендерите `Counter`, перший дочірній елемент `div` змінюється з `div` на `section`. Коли дочірній елемент `div` було видалено з DOM, все дерево під ним (включаючи `Counter` та його стан) було також знищено.
-
+
-When `section` changes to `div`, the `section` is deleted and the new `div` is added
+Коли `section` змінюється на `div`, тоді `section` видаляється і новий `div` додається
@@ -686,21 +686,21 @@ When `section` changes to `div`, the `section` is deleted and the new `div` is a
-
+
-When switching back, the `div` is deleted and the new `section` is added
+При перемиканні назад, `div` видаляється і нова `section` додається
-As a rule of thumb, **if you want to preserve the state between re-renders, the structure of your tree needs to "match up"** from one render to another. If the structure is different, the state gets destroyed because React destroys state when it removes a component from the tree.
+Як правила, **якщо ви хочете зберегти стан між повторними рендерами, структура вашого дерева повинна "збігатися"** від одного рендера до іншого. Якщо структура відрізняється, стан знищується, оскільки React знищує стан, коли видаляє компонент із дерева.
-This is why you should not nest component function definitions.
+Ось чому вам не варто вкладати визначення функційних компонент.
-Here, the `MyTextField` component function is defined *inside* `MyComponent`:
+Тут, `MyTextField` функційний компонент визначено *всередині* `MyComponent`:
@@ -726,7 +726,7 @@ export default function MyComponent() {
+ }}>Натиснуто {counter} разів
>
);
}
@@ -735,13 +735,13 @@ export default function MyComponent() {
-Every time you click the button, the input state disappears! This is because a *different* `MyTextField` function is created for every render of `MyComponent`. You're rendering a *different* component in the same position, so React resets all state below. This leads to bugs and performance problems. To avoid this problem, **always declare component functions at the top level, and don't nest their definitions.**
+Кожного разу, коли ви натискаєте кнопку, стан введення зникає! Це відбувається тому, що *інша* `MyTextField` функція створюється на кожен рендер `MyComponent`. Ви рендерите *інший* компонент у тому самому місці, тому React скидає весь стан нижче. Це призводить до проблем та проблем із продуктивністю. Щоб уникнути цієї проблеми **завжди оголошуйте функційні компоненти на найвищому рівні і не вкладайте їхнє визначення.**
-## Resetting state at the same position {/*resetting-state-at-the-same-position*/}
+## Скидання стану в тому самому місці {/*resetting-state-at-the-same-position*/}
-By default, React preserves state of a component while it stays at the same position. Usually, this is exactly what you want, so it makes sense as the default behavior. But sometimes, you may want to reset a component's state. Consider this app that lets two players keep track of their scores during each turn:
+За замовчуванням, React зберігає стан компонента, поки він залишається на тому самому місці. Зазвичай, це саме те, що ви хочете, тому це має сенс як поведінка за замовчуванням. Але інколи вам може знадобитися скинути стан компонента. Розглянемо цей додаток, який дозволяє двом гравцям відстежувати свої результати під час кожного ходу:
@@ -753,14 +753,14 @@ export default function Scoreboard() {
return (
{isPlayerA ? (
-
+
) : (
-
+
)}
);
@@ -781,9 +781,9 @@ function Counter({ person }) {
onPointerEnter={() => setHover(true)}
onPointerLeave={() => setHover(false)}
>
-
{person}'s score: {score}
+
Рахунок {person}: {score}
);
@@ -796,7 +796,7 @@ h1 {
}
.counter {
- width: 100px;
+ width: 150px;
text-align: center;
border: 1px solid gray;
border-radius: 4px;
@@ -811,19 +811,19 @@ h1 {
-Currently, when you change the player, the score is preserved. The two `Counter`s appear in the same position, so React sees them as *the same* `Counter` whose `person` prop has changed.
+Зараз, коли ви змінюєте гравця, рахунок зберігається. Обидва `Counter` з'являються на одній і тій самій позиції, тому React сприймає їх як *один і той самий* `Counter`, у якого просто змінився проп `person`.
-But conceptually, in this app they should be two separate counters. They might appear in the same place in the UI, but one is a counter for Taylor, and another is a counter for Sarah.
+Але концептуально в цьому застосунку вони повинні бути двома окремими лічильниками. Вони можуть відображатися на одному й тому ж місці в інтерфейсі користувача, але один з них є лічильником для Тейлора, а інший — лічильником для Сари.
-There are two ways to reset state when switching between them:
+Є два способи скинути стан при перемиканні між ними:
-1. Render components in different positions
-2. Give each component an explicit identity with `key`
+1. Рендерити компоненти на різних позиціях
+2. Дати кожному компоненту явну ідентичність за допомогою `key`
-### Option 1: Rendering a component in different positions {/*option-1-rendering-a-component-in-different-positions*/}
+### Спосіб 1: Рендерити компонент в різних місцях {/*option-1-rendering-a-component-in-different-positions*/}
-If you want these two `Counter`s to be independent, you can render them in two different positions:
+Якщо ви хочете, щоб ці два `Counter`, були незалежними, вам потрібно рендерити їх в двох різних позиціях:
@@ -835,15 +835,15 @@ export default function Scoreboard() {
return (
{isPlayerA &&
-
+
}
{!isPlayerA &&
-
+
}
);
@@ -864,9 +864,9 @@ function Counter({ person }) {
onPointerEnter={() => setHover(true)}
onPointerLeave={() => setHover(false)}
>
-
{person}'s score: {score}
+
Рахунок {person}: {score}
);
@@ -879,7 +879,7 @@ h1 {
}
.counter {
- width: 100px;
+ width: 150px;
text-align: center;
border: 1px solid gray;
border-radius: 4px;
@@ -894,42 +894,42 @@ h1 {
-* Initially, `isPlayerA` is `true`. So the first position contains `Counter` state, and the second one is empty.
-* When you click the "Next player" button the first position clears but the second one now contains a `Counter`.
+* Спочатку `isPlayerA` дорівнює `true`. Тому перша позиція містить стан `Counter`, а друга — порожня.
+* Коли ви натискаєте кнопку "Наступний гравець", перша позиція очищується, а друга тепер містить `Counter`.
-
+
-Initial state
+Початковий стан
-
+
-Clicking "next"
+Натискання "наступний"
-
+
-Clicking "next" again
+Натискання "наступний" знову
-Each `Counter`'s state gets destroyed each time it's removed from the DOM. This is why they reset every time you click the button.
+Стан кожного `Counter` знищується щоразу, коли його видаляють із DOM. Саме тому вони скидаються щоразу, коли ви натискаєте кнопку.
-This solution is convenient when you only have a few independent components rendered in the same place. In this example, you only have two, so it's not a hassle to render both separately in the JSX.
+Це рішення зручне, коли у вас лише кілька незалежних компонент, які рендеряться на одному місці. У цьому прикладі їх лише два, тому не складно рендерити обидві окремо в JSX.
-### Option 2: Resetting state with a key {/*option-2-resetting-state-with-a-key*/}
+### Спосіб 2: Скидання стану за допомогою ключа {/*option-2-resetting-state-with-a-key*/}
-There is also another, more generic, way to reset a component's state.
+Існує також інший, більш загальний спосіб скидання стану компонента.
-You might have seen `key`s when [rendering lists.](/learn/rendering-lists#keeping-list-items-in-order-with-key) Keys aren't just for lists! You can use keys to make React distinguish between any components. By default, React uses order within the parent ("first counter", "second counter") to discern between components. But keys let you tell React that this is not just a *first* counter, or a *second* counter, but a specific counter--for example, *Taylor's* counter. This way, React will know *Taylor's* counter wherever it appears in the tree!
+Ви могли бачити `key` коли [рендерите списки.](/learn/rendering-lists#keeping-list-items-in-order-with-key) Ключі не тільки для списків! Ви можете використовувати ключі, щоб React розрізняв будь-які компоненти. За замовчуванням React використовує порядок в середині батьківського елемента ("перший лічильник", "другий лічильник"), щоб розрізняти компоненти. Але ключі дають можливість вам сказати до React, що це не просто *перший* лічильник або *другий* лічильник а конкретний лічильник — для прикладу, лічильник *Тайлера*. Таким чином, React буде знати лічильник *Тайлера* будь-коли він з'явиться в дереві!
-In this example, the two ``s don't share state even though they appear in the same place in JSX:
+В цьому прикладі, два `` не поширюють стан, хоча вони появляються в одному місці в JSX:
@@ -941,14 +941,14 @@ export default function Scoreboard() {
return (
{isPlayerA ? (
-
+
) : (
-
+
)}
);
@@ -969,9 +969,9 @@ function Counter({ person }) {
onPointerEnter={() => setHover(true)}
onPointerLeave={() => setHover(false)}
>
-
{person}'s score: {score}
+
Рахунок {person}: {score}
);
@@ -984,7 +984,7 @@ h1 {
}
.counter {
- width: 100px;
+ width: 150px;
text-align: center;
border: 1px solid gray;
border-radius: 4px;
@@ -999,29 +999,29 @@ h1 {
-Switching between Taylor and Sarah does not preserve the state. This is because **you gave them different `key`s:**
+Переключення між станом Тайлера і Сари не зберігає стан. Це тому що **ви дали їм різні `key`:**
```js
{isPlayerA ? (
-
+
) : (
-
+
)}
```
-Specifying a `key` tells React to use the `key` itself as part of the position, instead of their order within the parent. This is why, even though you render them in the same place in JSX, React sees them as two different counters, and so they will never share state. Every time a counter appears on the screen, its state is created. Every time it is removed, its state is destroyed. Toggling between them resets their state over and over.
+Вказуючи `key` ви кажете React використовувати `key` як частину місця розташування замість його власного порядку в середині батьківського елемента. Саме через це, навіть якщо ви рендерите їх в одному місці в JSX, React бачить їх як два різних лічильника, саме тому вони ніколи не поширюватимуть стан. Кожного разу коли лічильник появляється на екрані, його стан створюється. Кожен раз коли він видалений, його стан знищується. Переключення між ними скидає їхній стан знову і знову.
-Remember that keys are not globally unique. They only specify the position *within the parent*.
+Пам'ятайте, що ключі не є глобально унікальними. Вони лише визначають позицію *в середині батьківського елемента*.
-### Resetting a form with a key {/*resetting-a-form-with-a-key*/}
+### Скидання форми за допомогою ключа {/*resetting-a-form-with-a-key*/}
-Resetting state with a key is particularly useful when dealing with forms.
+Скидання стану за допомогою ключа є особливо корисне при роботі з формами.
-In this chat app, the `` component contains the text input state:
+В цьому чат-застосунку компонент `` містить стан поля введення тексту:
@@ -1045,9 +1045,9 @@ export default function Messenger() {
}
const contacts = [
- { id: 0, name: 'Taylor', email: 'taylor@mail.com' },
- { id: 1, name: 'Alice', email: 'alice@mail.com' },
- { id: 2, name: 'Bob', email: 'bob@mail.com' }
+ { id: 0, name: 'Тайлер', email: 'taylor@mail.com' },
+ { id: 1, name: 'Аліса', email: 'alice@mail.com' },
+ { id: 2, name: 'Боб', email: 'bob@mail.com' }
];
```
@@ -1084,11 +1084,11 @@ export default function Chat({ contact }) {
);
}
@@ -1116,17 +1116,17 @@ textarea {
-Try entering something into the input, and then press "Alice" or "Bob" to choose a different recipient. You will notice that the input state is preserved because the `` is rendered at the same position in the tree.
+Спробуйте ввести щось в поле введення і потім натиснути "Аліса" або "Боб" щоб вибрати іншого отримувача. Ви помітите, що стан поля введення збережено, тому що `` рендериться в тому самому місці в дереві.
-**In many apps, this may be the desired behavior, but not in a chat app!** You don't want to let the user send a message they already typed to a wrong person due to an accidental click. To fix it, add a `key`:
+**В більшості застосунків це може бути бажана поведінка але не в чат-застосунку!** Ви не хочете дозволити користувачу надіслати повідомлення, яке вони вже написали до іншої особи через випадкове натискання. Щоб виправити це, додайте `key`:
```js
```
-This ensures that when you select a different recipient, the `Chat` component will be recreated from scratch, including any state in the tree below it. React will also re-create the DOM elements instead of reusing them.
+Це гарантує, що коли ви виберете іншого отримувача, компонент `Chat` буде створено заново, разом із усім станом у дереві під ним. React також створить нові DOM-елементи замість повторного використання старих.
-Now switching the recipient always clears the text field:
+Тепер при перемиканні отримувача поле введення завжди очищується:
@@ -1150,9 +1150,9 @@ export default function Messenger() {
}
const contacts = [
- { id: 0, name: 'Taylor', email: 'taylor@mail.com' },
- { id: 1, name: 'Alice', email: 'alice@mail.com' },
- { id: 2, name: 'Bob', email: 'bob@mail.com' }
+ { id: 0, name: 'Тайлер', email: 'taylor@mail.com' },
+ { id: 1, name: 'Аліса', email: 'alice@mail.com' },
+ { id: 2, name: 'Боб', email: 'bob@mail.com' }
];
```
@@ -1189,11 +1189,11 @@ export default function Chat({ contact }) {
);
}
@@ -1223,24 +1223,24 @@ textarea {
-#### Preserving state for removed components {/*preserving-state-for-removed-components*/}
+#### Збереження стану для видалених компонент {/*preserving-state-for-removed-components*/}
-In a real chat app, you'd probably want to recover the input state when the user selects the previous recipient again. There are a few ways to keep the state "alive" for a component that's no longer visible:
+В справжньому чат-застосунку, ви можливо захочете відновити стан поля введення коли користувач знову вибирає попереднього отримувача. Є декілька способів, щоб зберегти стан "живим" для компоненти, що більше не є видимою:
-- You could render _all_ chats instead of just the current one, but hide all the others with CSS. The chats would not get removed from the tree, so their local state would be preserved. This solution works great for simple UIs. But it can get very slow if the hidden trees are large and contain a lot of DOM nodes.
-- You could [lift the state up](/learn/sharing-state-between-components) and hold the pending message for each recipient in the parent component. This way, when the child components get removed, it doesn't matter, because it's the parent that keeps the important information. This is the most common solution.
-- You might also use a different source in addition to React state. For example, you probably want a message draft to persist even if the user accidentally closes the page. To implement this, you could have the `Chat` component initialize its state by reading from the [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), and save the drafts there too.
+- Ви можете рендерити _всі_ чати замість одного поточного але сховати всі інші за допомогою CSS. Чати не будуть видалені із дерева, тому їхній локальний стан буде збережено. Це рішення добре працює для простих інтерфейсів користувача. Але, воно може стати дуже повільним, якщо приховані дерева великі та містять багато DOM-вузлів.
+- Ви можете [підняти стан вгору](/learn/sharing-state-between-components) і тримати очікуване повідомлення для кожного отримувача в батьківському компоненті. Цим методом, коли дочірній компонент буде видалено, це немає значення, тому що його батько зберігає важливу інформацію. Це найпоширеніше рішення.
+- Ви також можете використовувати інший джерело разом із станом React. Для прикладу, ви можливо хочете, щоб чернетка із повідомленням була присутня навіть коли користувач випадково закрив сторінку. Щоб реалізувати це, вам потрібно щоб `Chat` компонент ініціалізував власний стан і читав його із [`локального сховища`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), та зберігав чернетку там.
-No matter which strategy you pick, a chat _with Alice_ is conceptually distinct from a chat _with Bob_, so it makes sense to give a `key` to the `` tree based on the current recipient.
+Не залежно від того, яку стратегію ви оберете, чат _із Алісою_ концептуально відрізняється від чату _з Бобом_, тому є сенс надати `ключ` до `` дерева на основі поточного отримувача.
-- React keeps state for as long as the same component is rendered at the same position.
-- State is not kept in JSX tags. It's associated with the tree position in which you put that JSX.
-- You can force a subtree to reset its state by giving it a different key.
-- Don't nest component definitions, or you'll reset state by accident.
+- React Зберігає стан доти, доки той самий компонент відрендерений в тому самому місці.
+- Стан не зберігається в JSX-тегах. Він пов'язаний з позицією дерева, де ви помістили цей JSX.
+- Ви можете примусити піддерево скинути власний стан даючи йому інший ключ.
+- Не вкладайте визначення компонентів, інакше ви випадково скинете стан.
@@ -1248,9 +1248,9 @@ No matter which strategy you pick, a chat _with Alice_ is conceptually distinct
-#### Fix disappearing input text {/*fix-disappearing-input-text*/}
+#### Виправити зникнення введеного тексту {/*fix-disappearing-input-text*/}
-This example shows a message when you press the button. However, pressing the button also accidentally resets the input. Why does this happen? Fix it so that pressing the button does not reset the input text.
+В цьому прикладі показано повідомлення коли ви натискаєте на кнопку. Однак, натискання кнопки також випадково очищає поле введення. Чому це трапляється? Виправте це, щоб під час натискання кнопки поле для введення не очищувалось.
@@ -1262,11 +1262,11 @@ export default function App() {
if (showHint) {
return (
-
Hint: Your favorite city?
+
Підказка: Яке ваше улюблене місто?
+ }}>Сховати підказку
);
}
@@ -1275,7 +1275,7 @@ export default function App() {
+ }}>Показати підказку
);
}
@@ -1299,9 +1299,9 @@ textarea { display: block; margin: 10px 0; }
-The problem is that `Form` is rendered in different positions. In the `if` branch, it is the second child of the `
`, but in the `else` branch, it is the first child. Therefore, the component type in each position changes. The first position changes between holding a `p` and a `Form`, while the second position changes between holding a `Form` and a `button`. React resets the state every time the component type changes.
+Проблема в тому, що `Form` рендериться в різних позиціях. У гілці `if` він є другим дочірнім елементом `
`, а у гілці `else` він є першим дочірнім елементом. Тому тип компонента на кожній позиції змінюється. Перша позиція змінюється між `p` та `Form`, коли друга позиція змінюється між `Form` та `button`. React скидає стан щоразу, коли тип компонента змінюється.
-The easiest solution is to unify the branches so that `Form` always renders in the same position:
+Найлегшим рішенням є об'єднання гілок, щоб `Form` завжди рендерився в одному і тому ж положені:
@@ -1313,17 +1313,17 @@ export default function App() {
return (
);
@@ -1347,7 +1347,7 @@ textarea { display: block; margin: 10px 0; }
-Technically, you could also add `null` before `` in the `else` branch to match the `if` branch structure:
+Технічно, ви також можете добавити `null` перед `` в гілці `else`, щоб відповідати структурі `if` гілки:
@@ -1359,11 +1359,11 @@ export default function App() {
if (showHint) {
return (
);
}
@@ -1395,19 +1395,19 @@ textarea { display: block; margin: 10px 0; }
-This way, `Form` is always the second child, so it stays in the same position and keeps its state. But this approach is much less obvious and introduces a risk that someone else will remove that `null`.
+У цьому випадку, `Form` завжди є другим дочірнім елементом, отже вона залишається на тому самому місці та зберігає стан. Але даний підхід є менш очевидним та представляє ризик, що хтось інший видалить цей `null`.
-#### Swap two form fields {/*swap-two-form-fields*/}
+#### Поміняти два поля форми {/*swap-two-form-fields*/}
-This form lets you enter first and last name. It also has a checkbox controlling which field goes first. When you tick the checkbox, the "Last name" field will appear before the "First name" field.
+Ця форма дозволяє вам ввести ім'я та прізвище. Вона також має прапорець, який контролює яке поле буде відображатись першим. Коли ви виберете прапорець, поле "Прізвище" появиться перед полем "Ім'я".
-It almost works, but there is a bug. If you fill in the "First name" input and tick the checkbox, the text will stay in the first input (which is now "Last name"). Fix it so that the input text *also* moves when you reverse the order.
+Це майже працює але є помилка. Якщо ви заповните поле "Ім'я" та виберете прапорець, то текст залишиться в першому поллі для введення (котре тепер "Прізвище"). Виправте це, щоб той текст поля введення *також* переміщався коли змінюється порядок.
-It seems like for these fields, their position within the parent is not enough. Is there some way to tell React how to match up the state between re-renders?
+Схоже, що для цих полів введення, їхня позиція в батьківському елементі не є достатньою. Чи є якийсь спосіб повідомити React, як узгодити стан між повторними рендерингами?
@@ -1425,22 +1425,22 @@ export default function App() {
checked={reverse}
onChange={e => setReverse(e.target.checked)}
/>
- Reverse order
+ Змінити порядок
);
if (reverse) {
return (
<>
-
-
+
+
{checkbox}
>
);
} else {
return (
<>
-
-
+
+
{checkbox}
>
);
@@ -1471,7 +1471,7 @@ label { display: block; margin: 10px 0; }
-Give a `key` to both `` components in both `if` and `else` branches. This tells React how to "match up" the correct state for either `` even if their order within the parent changes:
+Дайте `key` до обох `` компонентів в обох `if` та `else` гілках. Це повідомить React, як "зіставити" конкретний стан для кожного `` навіть коли їхній порядок в батьківському елементі змінюється:
@@ -1487,22 +1487,22 @@ export default function App() {
checked={reverse}
onChange={e => setReverse(e.target.checked)}
/>
- Reverse order
+ Змінити порядок
);
if (reverse) {
return (
<>
-
-
+
+
{checkbox}
>
);
} else {
return (
<>
-
-
+
+
{checkbox}
>
);
@@ -1533,11 +1533,11 @@ label { display: block; margin: 10px 0; }
-#### Reset a detail form {/*reset-a-detail-form*/}
+#### Скинути форми деталей {/*reset-a-detail-form*/}
-This is an editable contact list. You can edit the selected contact's details and then either press "Save" to update it, or "Reset" to undo your changes.
+Це список контактів, який можна редагувати. Ви можете редагувати дані вибраного контакту, а потім натиснути "Зберегти", щоб оновити їх, або "Скинути", щоб скасувати ваші зміни.
-When you select a different contact (for example, Alice), the state updates but the form keeps showing the previous contact's details. Fix it so that the form gets reset when the selected contact changes.
+Коли ви вибираєте інший контакт (для прикладу, Аліса), Стан змінюється але форма продовжує показувати дані попереднього контакту. Виправте це так, щоб форма скидалася при зміні вибраного контакту.
@@ -1587,9 +1587,9 @@ export default function ContactManager() {
}
const initialContacts = [
- { id: 0, name: 'Taylor', email: 'taylor@mail.com' },
- { id: 1, name: 'Alice', email: 'alice@mail.com' },
- { id: 2, name: 'Bob', email: 'bob@mail.com' }
+ { id: 0, name: 'Тайлер', email: 'taylor@mail.com' },
+ { id: 1, name: 'Аліса', email: 'alice@mail.com' },
+ { id: 2, name: 'Боб', email: 'bob@mail.com' }
];
```
@@ -1629,7 +1629,7 @@ export default function EditContact({ initialData, onSave }) {
return (
);
@@ -1689,7 +1689,7 @@ button {
-Give `key={selectedId}` to the `EditContact` component. This way, switching between different contacts will reset the form:
+Дайте `key={selectedId}` до `EditContact` компонента. Таким чином, перемикання між різними контактами буде скидати форму:
@@ -1740,9 +1740,9 @@ export default function ContactManager() {
}
const initialContacts = [
- { id: 0, name: 'Taylor', email: 'taylor@mail.com' },
- { id: 1, name: 'Alice', email: 'alice@mail.com' },
- { id: 2, name: 'Bob', email: 'bob@mail.com' }
+ { id: 0, name: 'Тайлер', email: 'taylor@mail.com' },
+ { id: 1, name: 'Аліса', email: 'alice@mail.com' },
+ { id: 2, name: 'Боб', email: 'bob@mail.com' }
];
```
@@ -1782,7 +1782,7 @@ export default function EditContact({ initialData, onSave }) {
return (
);
@@ -1842,13 +1842,13 @@ button {
-#### Clear an image while it's loading {/*clear-an-image-while-its-loading*/}
+#### Очистити зображення під час його завантаження {/*clear-an-image-while-its-loading*/}
-When you press "Next", the browser starts loading the next image. However, because it's displayed in the same `` tag, by default you would still see the previous image until the next one loads. This may be undesirable if it's important for the text to always match the image. Change it so that the moment you press "Next", the previous image immediately clears.
+Коли ви натискаєте "Далі", браузер починає завантажувати наступне зображення. Однак, тому що воно відображається в тому самому тегу ``, то за замовчуванням ви будете бачити попереднє зображення до того моменту поки не завантажиться наступне. Це може бути небажаним, якщо важливо, щоб текст завжди відповідав зображенню. Змініть це так, щоб коли ви натискаєте "Далі", попереднє зображення моментально очищається When you press "Next", the browser starts loading the next image. However, because it's displayed in the same `` tag, by default you would still see the previous image until the next one loads. This may be undesirable if it's important for the text to always match the image. Change it so that the moment you press "Next", the previous image immediately clears.
-Is there a way to tell React to re-create the DOM instead of reusing it?
+Чи є спосіб сказати React перестворювати DOM замість того, щоб його перевикористання?
@@ -1873,10 +1873,10 @@ export default function Gallery() {
return (
<>
- Image {index + 1} of {images.length}
+ Зображення {index + 1} of {images.length}
@@ -1918,7 +1918,7 @@ img { width: 150px; height: 150px; }
-You can provide a `key` to the `` tag. When that `key` changes, React will re-create the `` DOM node from scratch. This causes a brief flash when each image loads, so it's not something you'd want to do for every image in your app. But it makes sense if you want to ensure the image always matches the text.
+Ви можете надати `key` до `` тегу. Коли цей `key` змінюється, React перестворює `` DOM-вузол з нуля. Це спричиняє коротке миготіння під час завантаження кожного зображення, отже це може бути не те, що ви захочете робити для кожного зображення в вашому застосунку. Але це доцільно, якщо ви хочете переконатись, що зображення завжди відповідало тексту.
@@ -1941,10 +1941,10 @@ export default function Gallery() {
return (
<>
- Image {index + 1} of {images.length}
+ Зображення {index + 1} of {images.length}
-#### Fix misplaced state in the list {/*fix-misplaced-state-in-the-list*/}
+#### Виправити неправильне розміщення стану в списку {/*fix-misplaced-state-in-the-list*/}
-In this list, each `Contact` has state that determines whether "Show email" has been pressed for it. Press "Show email" for Alice, and then tick the "Show in reverse order" checkbox. You will notice that it's _Taylor's_ email that is expanded now, but Alice's--which has moved to the bottom--appears collapsed.
+В списку, кожний `Contact` має стан, що визначає чи "Показати пошту" буде натиснуте для цього. Натисніть "Показати пошту" для Аліси, І потім виберіть "Показати в зворотному порядку" прапорець. Ви помітите, що пошта _Тайлера_ розгорнута але пошта Аліси, яка була перенесена в низ, згорнута.
-Fix it so that the expanded state is associated with each contact, regardless of the chosen ordering.
+Виправте, це так, щоб розгорнутий стан відповідав кожному контакту, не зважаючи на вибраний порядок.
@@ -2016,7 +2016,7 @@ export default function ContactList() {
setReverse(e.target.checked)
}}
/>{' '}
- Show in reverse order
+ Показати в зворотному порядку
{displayedContacts.map((contact, i) =>
@@ -2030,9 +2030,9 @@ export default function ContactList() {
}
const contacts = [
- { id: 0, name: 'Alice', email: 'alice@mail.com' },
+ { id: 0, name: 'Аліса', email: 'alice@mail.com' },
{ id: 1, name: 'Bob', email: 'bob@mail.com' },
- { id: 2, name: 'Taylor', email: 'taylor@mail.com' }
+ { id: 2, name: 'Тайлер', email: 'taylor@mail.com' }
];
```
@@ -2050,7 +2050,7 @@ export default function Contact({ contact }) {
>
);
@@ -2080,16 +2080,16 @@ button {
-The problem is that this example was using index as a `key`:
+Проблемою є те, що в цьому прикладі було використано індекс як `key`:
```js
{displayedContacts.map((contact, i) =>
```
-However, you want the state to be associated with _each particular contact_.
+Однак ви хочете, щоб стан був пов'язаний з _кожним конкретним контактом_.
-Using the contact ID as a `key` instead fixes the issue:
+Використання ідентифікатора контакту як `key` вирішує цю проблему:
@@ -2115,7 +2115,7 @@ export default function ContactList() {
setReverse(e.target.checked)
}}
/>{' '}
- Show in reverse order
+ Показати в зворотному порядку
-State is associated with the tree position. A `key` lets you specify a named position instead of relying on order.
+Стан пов'язаний із позицією дерева. За допомогою `key` можна вказати позицію за назвою, а не покладатися на порядок.