From 72afc7e75b478407a57849bca9c824b29f2e94e6 Mon Sep 17 00:00:00 2001 From: abobi Date: Wed, 18 Sep 2024 20:36:20 +0300 Subject: [PATCH 01/16] translated from start to title step1 --- .../learn/passing-data-deeply-with-context.md | 98 +++++++++---------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index 1aea87b35..b2f3bf8de 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -1,48 +1,48 @@ --- -title: Passing Data Deeply with Context +title: Передача данных через контекст --- -Usually, you will pass information from a parent component to a child component via props. But passing props can become verbose and inconvenient if you have to pass them through many components in the middle, or if many components in your app need the same information. *Context* lets the parent component make some information available to any component in the tree below it—no matter how deep—without passing it explicitly through props. +Обычно вы передаёте информацию от родительского компонента к дочернему с помощью пропсов. Однако такая передача может стать многослойной и неудобной, если необходимо передавать информацию через множество промежуточных компонентов или если многим компонентам в вашем приложении нужна одна и та же информация. *Контекст* позволяет родительскому компоненту передавать информацию любому компоненту в дереве под ним, независимо от глубины и не передавая данные явно через пропсы. -- What "prop drilling" is -- How to replace repetitive prop passing with context -- Common use cases for context -- Common alternatives to context +- Что такое "проп бурение" +- Как заменить повторяющуюся передачу пропсов +- Рядовые случаи использования контекста +- Альтернативы контекста -## The problem with passing props {/*the-problem-with-passing-props*/} +## Проблема передачи пропса {/*the-problem-with-passing-props*/} -[Passing props](/learn/passing-props-to-a-component) is a great way to explicitly pipe data through your UI tree to the components that use it. +[Передача пропсов](/learn/passing-props-to-a-component) — это отличный способ явно передать данные через UI дерево компонентам, которые их используют. -But passing props can become verbose and inconvenient when you need to pass some prop deeply through the tree, or if many components need the same prop. The nearest common ancestor could be far removed from the components that need data, and [lifting state up](/learn/sharing-state-between-components) that high can lead to a situation called "prop drilling". +Однако передача пропсов может стать муторной, если вам нужно передать их глубоко в дерево, или если многим компонентам нужен один и тот же пропс. Ближайший общий предок может находиться далеко от компонентов, которым нужны данные, и [подъём состояния вверх](/learn/sharing-state-between-components) на такую высоту может привести к ситуации, называемой «проп бурение». -Lifting state up +Подъём состояния -Prop drilling +Проп бурение -Wouldn't it be great if there were a way to "teleport" data to the components in the tree that need it without passing props? With React's context feature, there is! +Было замечательно, если бы существовал способ «телепортировать» данные в те компоненты дерева, которым они нужны, без передачи пропсов? С помощью функции React контекст это возможно! -## Context: an alternative to passing props {/*context-an-alternative-to-passing-props*/} +## Контекст: альтернатива передачи пропсов {/*context-an-alternative-to-passing-props*/} -Context lets a parent component provide data to the entire tree below it. There are many uses for context. Here is one example. Consider this `Heading` component that accepts a `level` for its size: +Контекст позволяет родительскому компоненту предоставлять данные всему дереву под ним. Существует множество вариантов использования контекста. Вот один из примеров. Рассмотрим компонент `Heading`, который принимает значение `level` для своего размера: @@ -53,12 +53,12 @@ import Section from './Section.js'; export default function Page() { return (
- Title - Heading - Sub-heading - Sub-sub-heading - Sub-sub-sub-heading - Sub-sub-sub-sub-heading + Наименование + Заголовок + Под-заголовок + Под-под-заголовок + Под-под-под-заголовок + Под-под-под-под-заголовок
); } @@ -90,7 +90,7 @@ export default function Heading({ level, children }) { case 6: return
{children}
; default: - throw Error('Unknown level: ' + level); + throw Error('Неизвестный уровень: ' + level); } } ``` @@ -106,7 +106,7 @@ export default function Heading({ level, children }) {
-Let's say you want multiple headings within the same `Section` to always have the same size: +Допустим, вы хотите, чтобы несколько заголовков в одном `Section` всегда имели одинаковый размер: @@ -117,19 +117,19 @@ import Section from './Section.js'; export default function Page() { return (
- Title + Наименование
- Heading - Heading - Heading + Заголовок + Заголовок + Заголовок
- Sub-heading - Sub-heading - Sub-heading + Под-заголовок + Под-заголовок + Под-заголовок
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + Под-под-заголовок + Под-под-заголовок + Под-под-заголовок
@@ -164,7 +164,7 @@ export default function Heading({ level, children }) { case 6: return
{children}
; default: - throw Error('Unknown level: ' + level); + throw Error('Неизвестный уровень: ' + level); } } ``` @@ -180,47 +180,47 @@ export default function Heading({ level, children }) { -Currently, you pass the `level` prop to each `` separately: +Сейчас вы передаёте проп `level` каждому `` отдельно: ```js
- About - Photos - Videos + О нас + Фото + Видео
``` -It would be nice if you could pass the `level` prop to the `
` component instead and remove it from the ``. This way you could enforce that all headings in the same section have the same size: +Было неплохо, если бы мы могли передавать параметр `level` в компонент `
` и убирать его из ``. Таким образом, мы можем добиться того, чтобы все заголовки в одном разделе имели одинаковый размер: ```js
- About - Photos - Videos + О нас + Фото + Видео
``` -But how can the `` component know the level of its closest `
`? **That would require some way for a child to "ask" for data from somewhere above in the tree.** +Но как компонент `` может узнать уровень ближайшего к нему `
`? **Это потребует от дочернего компонента какого-то способа «запрашивать» данные откуда-то сверху.** -You can't do it with props alone. This is where context comes into play. You will do it in three steps: +С помощью одних только пропсов этого не сделать. Здесь на помощь приходит контекст. Вы можете сделать это в три шага: -1. **Create** a context. (You can call it `LevelContext`, since it's for the heading level.) -2. **Use** that context from the component that needs the data. (`Heading` will use `LevelContext`.) -3. **Provide** that context from the component that specifies the data. (`Section` will provide `LevelContext`.) +1. **Создать** контекст. (Вы можете назвать его `LevelContext`, поскольку он предназначен для уровня заголовка). +2. **Использовать** этот контекст в компоненте, которому нужны данные. (`Heading` будет использовать `LevelContext`). +3. **Предоставить** этот контекст компоненту, определяющему данные. (`Section` предоставит `LevelContext`). -Context lets a parent--even a distant one!--provide some data to the entire tree inside of it. +Контекст позволяет родительскому компоненту — даже удалённому — предоставлять определённые данные всему дереву компонентов внутри него. -Using context in close children +Использование контекста с детьми вблизи -Using context in distant children +Использование контекста с детьми на расстоянии From 611ed2c37474ad2e00ca563f9101bb25264aefb1 Mon Sep 17 00:00:00 2001 From: abobi Date: Thu, 19 Sep 2024 13:40:43 +0300 Subject: [PATCH 02/16] translated from step1 to title context passes... --- .../learn/passing-data-deeply-with-context.md | 152 +++++++++--------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index b2f3bf8de..b9fd6714e 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -226,9 +226,9 @@ export default function Heading({ level, children }) { -### Step 1: Create the context {/*step-1-create-the-context*/} +### Шаг 1: Создать контекст {/*step-1-create-the-context*/} -First, you need to create the context. You'll need to **export it from a file** so that your components can use it: +Сначала нужно создать контекст. Потом вам нужно будет **экспортировать его из файла**, чтобы ваши компоненты могли его использовать: @@ -239,19 +239,19 @@ import Section from './Section.js'; export default function Page() { return (
- Title + Наименование
- Heading - Heading - Heading + Заголовок + Заголовок + Заголовок
- Sub-heading - Sub-heading - Sub-heading + Под-заголовок + Под-заголовок + Под-заголовок
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + Под-под-заголовок + Под-под-заголовок + Под-под-заголовок
@@ -286,7 +286,7 @@ export default function Heading({ level, children }) { case 6: return
{children}
; default: - throw Error('Unknown level: ' + level); + throw Error('Неизвестный уровень: ' + level); } } ``` @@ -308,18 +308,18 @@ export const LevelContext = createContext(1); -The only argument to `createContext` is the _default_ value. Here, `1` refers to the biggest heading level, but you could pass any kind of value (even an object). You will see the significance of the default value in the next step. +Единственным аргументом `createContext` является значение по _умолчанию_. Здесь `1` означает самый большой уровень заголовка, но вы можете передать любое значение (даже объект). Значимость значения по умолчанию вы увидите в следующем шаге. -### Step 2: Use the context {/*step-2-use-the-context*/} +### Шаг 2: Использовать контекст {/*step-2-use-the-context*/} -Import the `useContext` Hook from React and your context: +Импортируем хук `useContext` и ваш контекст из React: ```js import { useContext } from 'react'; import { LevelContext } from './LevelContext.js'; ``` -Currently, the `Heading` component reads `level` from props: +Сейчас компонент `Heading` считывает `level` из пропсов: ```js export default function Heading({ level, children }) { @@ -327,7 +327,7 @@ export default function Heading({ level, children }) { } ``` -Instead, remove the `level` prop and read the value from the context you just imported, `LevelContext`: +Вместо этого удалите параметр `level` и прочитайте значение из контекста, который вы только что импортировали — `LevelContext`: ```js {2} export default function Heading({ children }) { @@ -336,29 +336,29 @@ export default function Heading({ children }) { } ``` -`useContext` is a Hook. Just like `useState` and `useReducer`, you can only call a Hook immediately inside a React component (not inside loops or conditions). **`useContext` tells React that the `Heading` component wants to read the `LevelContext`.** +`useContext` — это хук. Как и `useState`, и `useReducer`, его можно вызывать только непосредственно внутри компонента React (не в циклах или условиях). **`useContext` сообщает React, что компонент `Heading` хочет получить данные из `LevelContext`.** -Now that the `Heading` component doesn't have a `level` prop, you don't need to pass the level prop to `Heading` in your JSX like this anymore: +Теперь, когда компонент `Heading` больше не имеет свойство `level`, вам не нужно передавать этот проп внутрь `Heading` в ваш JSX как здесь: ```js
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + Под-под-заголовок + Под-под-заголовок + Под-под-заголовок
``` -Update the JSX so that it's the `Section` that receives it instead: +Обновите JSX так, чтобы компонент `Section` получал проп `level` как в примере: ```jsx
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + Под-под-заголовок + Под-под-заголовок + Под-под-заголовок
``` -As a reminder, this is the markup that you were trying to get working: +Вспомним, что это тот код, который вы пытались заставить работать: @@ -369,19 +369,19 @@ import Section from './Section.js'; export default function Page() { return (
- Title + Наименование
- Heading - Heading - Heading + Заголовок + Заголовок + Заголовок
- Sub-heading - Sub-heading - Sub-heading + Под-заголовок + Под-заголовок + Под-заголовок
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + Под-под-заголовок + Под-под-заголовок + Под-под-заголовок
@@ -420,7 +420,7 @@ export default function Heading({ children }) { case 6: return
{children}
; default: - throw Error('Unknown level: ' + level); + throw Error('Неизвестный уровень: ' + level); } } ``` @@ -442,13 +442,13 @@ export const LevelContext = createContext(1); -Notice this example doesn't quite work, yet! All the headings have the same size because **even though you're *using* the context, you have not *provided* it yet.** React doesn't know where to get it! +Обратите внимание, что этот пример еще не совсем рабочий! Все заголовки имеют одинаковый размер, потому что **хоть вы и *используете* контекст, вы еще не *указали* его.** React не знает, где его взять! -If you don't provide the context, React will use the default value you've specified in the previous step. In this example, you specified `1` as the argument to `createContext`, so `useContext(LevelContext)` returns `1`, setting all those headings to `

`. Let's fix this problem by having each `Section` provide its own context. +Если вы не укажете контекст, React будет использовать значение по умолчанию, которое вы указали на предыдущем шаге. В этом примере вы указали `1` в качестве аргумента для `createContext`, поэтому `useContext(LevelContext)` возвращает `1`, устанавливая для всех заголовков `

` это значение. Давайте исправим эту проблему, заставив каждый `Section` предоставлять свой собственный контекст. -### Step 3: Provide the context {/*step-3-provide-the-context*/} +### Шаг 3: Указать контекст {/*step-3-provide-the-context*/} -The `Section` component currently renders its children: +Компонент `Section` в данный момент отображает свои дочерние элементы: ```js export default function Section({ children }) { @@ -460,7 +460,7 @@ export default function Section({ children }) { } ``` -**Wrap them with a context provider** to provide the `LevelContext` to them: +**Оберните их провайдером контекста**, чтобы предоставить им `LevelContext`: ```js {1,6,8} import { LevelContext } from './LevelContext.js'; @@ -476,7 +476,7 @@ export default function Section({ level, children }) { } ``` -This tells React: "if any component inside this `
` asks for `LevelContext`, give them this `level`." The component will use the value of the nearest `` in the UI tree above it. +Это сообщает React: "если какой-либо компонент внутри `
` запрашивает `LevelContext`, дайте ему этот уровень." Компонент будет использовать значение ближайшего `` в дереве UI над ним. @@ -487,19 +487,19 @@ import Section from './Section.js'; export default function Page() { return (
- Title + Наименование
- Heading - Heading - Heading + Заголовок + Заголовок + Заголовок
- Sub-heading - Sub-heading - Sub-heading + Под-заголовок + Под-заголовок + Под-заголовок
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + Под-под-заголовок + Под-под-заголовок + Под-под-заголовок
@@ -542,7 +542,7 @@ export default function Heading({ children }) { case 6: return
{children}
; default: - throw Error('Unknown level: ' + level); + throw Error('Неизвестный уровень: ' + level); } } ``` @@ -564,15 +564,15 @@ export const LevelContext = createContext(1); -It's the same result as the original code, but you did not need to pass the `level` prop to each `Heading` component! Instead, it "figures out" its heading level by asking the closest `Section` above: +Это тот же результат, что и в исходном коде, но вам не нужно передавать проп `level` каждому компоненту `Heading`! Вместо этого он «выясняет» уровень своего заголовка, запрашивая ближайший `Section` выше: -1. You pass a `level` prop to the `
`. -2. `Section` wraps its children into ``. -3. `Heading` asks the closest value of `LevelContext` above with `useContext(LevelContext)`. +1. Вы передаёте проп `level` в `
`. +2. `Section` оборачивает дочерние элементы в ``. +3. `Heading` запрашивает ближайшее значение `LevelContext` с помощью `useContext(LevelContext)`. -## Using and providing context from the same component {/*using-and-providing-context-from-the-same-component*/} +## Использование и предоставление контекста в одном и том же компоненте {/*using-and-providing-context-from-the-same-component*/} -Currently, you still have to specify each section's `level` manually: +В настоящее время вам по-прежнему приходится указывать `level` каждого раздела вручную: ```js export default function Page() { @@ -585,7 +585,7 @@ export default function Page() { ... ``` -Since context lets you read information from a component above, each `Section` could read the `level` from the `Section` above, and pass `level + 1` down automatically. Here is how you could do it: +Так как контекст позволяет считывать информацию из компонента выше, каждый `Section` может считывать `level` из `Section` выше, и автоматически передавать `level + 1` вниз. Вот как это можно сделать: ```js src/Section.js {5,8} import { useContext } from 'react'; @@ -603,7 +603,7 @@ export default function Section({ children }) { } ``` -With this change, you don't need to pass the `level` prop *either* to the `
` or to the ``: +Благодаря этому изменению вам не нужно передавать параметр `level` *какому либо* `
` или ``: @@ -614,19 +614,19 @@ import Section from './Section.js'; export default function Page() { return (
- Title + Наименование
- Heading - Heading - Heading + Заголовок + Заголовок + Заголовок
- Sub-heading - Sub-heading - Sub-heading + Под-заголовок + Под-заголовок + Под-заголовок
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + Под-под-заголовок + Под-под-заголовок + Под-под-заголовок
@@ -695,11 +695,11 @@ export const LevelContext = createContext(0); -Now both `Heading` and `Section` read the `LevelContext` to figure out how "deep" they are. And the `Section` wraps its children into the `LevelContext` to specify that anything inside of it is at a "deeper" level. +Теперь и `Heading`, и `Section` читают `LevelContext`, чтобы выяснить, насколько "глубоко" они находятся. А `Section` оборачивает свои дочерние элементы в `LevelContext`, чтобы указать, что все, что находится внутри него, находится на более "глубоком" уровне. -This example uses heading levels because they show visually how nested components can override context. But context is useful for many other use cases too. You can pass down any information needed by the entire subtree: the current color theme, the currently logged in user, and so on. +В этом примере используются уровни заголовков, потому что они наглядно показывают, как вложенные компоненты могут переопределять контекст. Но контекст полезен и во многих других случаях. Вы можете передать любую информацию, необходимую всему поддереву: текущую цветовую тему, пользователя вошедшего в систему, и так далее. From d53c18e8e17f60c9dd0a96234867ab4a60d40d9e Mon Sep 17 00:00:00 2001 From: abobi Date: Fri, 20 Sep 2024 21:50:25 +0300 Subject: [PATCH 03/16] translated from 'context passes...' to end --- .../learn/passing-data-deeply-with-context.md | 152 +++++++++--------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index b9fd6714e..0ca873f7b 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -21,7 +21,7 @@ title: Передача данных через контекст [Передача пропсов](/learn/passing-props-to-a-component) — это отличный способ явно передать данные через UI дерево компонентам, которые их используют. -Однако передача пропсов может стать муторной, если вам нужно передать их глубоко в дерево, или если многим компонентам нужен один и тот же пропс. Ближайший общий предок может находиться далеко от компонентов, которым нужны данные, и [подъём состояния вверх](/learn/sharing-state-between-components) на такую высоту может привести к ситуации, называемой «проп бурение». +Однако передача пропсов может стать муторной, если вам нужно передать их глубоко в дерево, или если многим компонентам нужен один и тот же проп. Ближайший общий предок может находиться далеко от компонентов, которым нужны данные, и [подъём состояния вверх](/learn/sharing-state-between-components) на такую высоту может привести к ситуации, называемой «проп бурение». @@ -703,11 +703,11 @@ export const LevelContext = createContext(0); -## Context passes through intermediate components {/*context-passes-through-intermediate-components*/} +## Прохождение контекста через промежуточные компоненты {/*context-passes-through-intermediate-components*/} -You can insert as many components as you like between the component that provides context and the one that uses it. This includes both built-in components like `
` and components you might build yourself. +Вы можете использовать столько компонентов, между предоставляющим контекст, и тем, который его использует компонентами, сколько захотите. Сюда входят как базовые компоненты, такие как `
`, так и те, которые вы можете создать самостоятельно. -In this example, the same `Post` component (with a dashed border) is rendered at two different nesting levels. Notice that the `` inside of it gets its level automatically from the closest `
`: +В этом примере один и тот же компонент `Post` (с пунктирной границей) отображается на двух разных уровнях вложенности. Обратите внимание, что `` внутри него автоматически получает свой уровень из ближайшего `
`: @@ -718,10 +718,10 @@ import Section from './Section.js'; export default function ProfilePage() { return (
- My Profile + Мой профиль
@@ -731,7 +731,7 @@ export default function ProfilePage() { function AllPosts() { return (
- Posts + Пост
); @@ -740,14 +740,14 @@ function AllPosts() { function RecentPosts() { return (
- Recent Posts + Последние посты
); @@ -792,7 +792,7 @@ export default function Heading({ children }) { const level = useContext(LevelContext); switch (level) { case 0: - throw Error('Heading must be inside a Section!'); + throw Error('Heading должен находиться внутри раздела!'); case 1: return

{children}

; case 2: @@ -832,58 +832,58 @@ export const LevelContext = createContext(0);
-You didn't do anything special for this to work. A `Section` specifies the context for the tree inside it, so you can insert a `` anywhere, and it will have the correct size. Try it in the sandbox above! +Вы не сделали ничего волшебного, чтобы это заработало. `Section` определяет контекст для дерева внутри него, поэтому вы можете поставить `` в любое место, и он будет иметь правильный размер. Попробуйте это в песочнице выше! + +**Контекст позволяет вам писать компоненты, которые "адаптируются к своему окружению" и отображаются по-разному в зависимости от того, _где_ (или, другими словами, _в каком контексте_) они отображаются.** -**Context lets you write components that "adapt to their surroundings" and display themselves differently depending on _where_ (or, in other words, _in which context_) they are being rendered.** +То, как работает контекст, может напомнить вам о [наследовании свойств CSS.](https://developer.mozilla.org/ru/docs/Web/CSS/Inheritance) В нём вы можете указать `color: blue` для `
`, и любой узел DOM внутри него, независимо от его глубины, унаследует этот цвет, если только какой-либо другой узел DOM в середине не переопределит его на `color: green`. Аналогично, в React единственный способ переопределить контекст, поступающий сверху, — это обернуть дочерние элементы в провайдер контекста с другим значением. -How context works might remind you of [CSS property inheritance.](https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance) In CSS, you can specify `color: blue` for a `
`, and any DOM node inside of it, no matter how deep, will inherit that color unless some other DOM node in the middle overrides it with `color: green`. Similarly, in React, the only way to override some context coming from above is to wrap children into a context provider with a different value. +В CSS разные свойства, такие как `color` и `background-color`, не переопределяют друг друга. Вы можете установить во всех `
` свойство `color` на красный, не влияя на `background-color`. Аналогично, **разные контексты React не переопределяют друг друга.** Каждый контекст, который вы создаете с помощью `createContext()`, полностью отделен от других и связывает компоненты, использующие и предоставляющие *этот конкретный* контекст. Один компонент может использовать или предоставлять множество разных контекстов без проблем. -In CSS, different properties like `color` and `background-color` don't override each other. You can set all `
`'s `color` to red without impacting `background-color`. Similarly, **different React contexts don't override each other.** Each context that you make with `createContext()` is completely separate from other ones, and ties together components using and providing *that particular* context. One component may use or provide many different contexts without a problem. +## Перед использованием контекста {/*before-you-use-context*/} -## Before you use context {/*before-you-use-context*/} +Контекст — это очень заманчиво! Однако это также означает, что им слишком легко злоупотребить. **Если вам нужно просто передать какие-то пропсы на несколько уровней в глубину, это не значит, что вы должны передавать информацию через контекст.** -Context is very tempting to use! However, this also means it's too easy to overuse it. **Just because you need to pass some props several levels deep doesn't mean you should put that information into context.** +Вот несколько альтернатив, которые нужно рассмотреть, прежде чем использовать контекст: -Here's a few alternatives you should consider before using context: +1. **Начните с [передачи пропсов.](/learn/passing-props-to-a-component)** Если ваши компоненты достаточно простые, то нередко приходится передавать множество пропсов вниз через множество компонентов. Это может показаться трудоёмкой задачей, но так становится ясно, какие компоненты используют те или иные данные! Человек, обслуживающий ваш код, будет рад, что вы сделали поток данных явным с помощью пропсов. +2. **Извлекайте компоненты и [передавайте им JSX как `детям`](/learn/passing-props-to-a-component#passing-jsx-as-children).** Если вы передаете какие-то данные через множество промежуточных компонентов, которые не используют эти данные (а только передают их дальше вниз), это часто означает, что вы забыли извлечь некоторые компоненты на этом пути. Например, вы передаете такие пропсы данных, как `posts`, визуальным компонентам, которые не используют их напрямую, например ``. Вместо этого сделайте так, чтобы `Layout` принимал `children` в качестве проп, и выводил ``. Это уменьшает количество слоев между компонентом, задающим данные, и компонентом, которому они нужны. -1. **Start by [passing props.](/learn/passing-props-to-a-component)** If your components are not trivial, it's not unusual to pass a dozen props down through a dozen components. It may feel like a slog, but it makes it very clear which components use which data! The person maintaining your code will be glad you've made the data flow explicit with props. -2. **Extract components and [pass JSX as `children`](/learn/passing-props-to-a-component#passing-jsx-as-children) to them.** If you pass some data through many layers of intermediate components that don't use that data (and only pass it further down), this often means that you forgot to extract some components along the way. For example, maybe you pass data props like `posts` to visual components that don't use them directly, like ``. Instead, make `Layout` take `children` as a prop, and render ``. This reduces the number of layers between the component specifying the data and the one that needs it. +Если ни один из этих подходов вам не подходит, рассмотрите контекст. -If neither of these approaches works well for you, consider context. +## Варианты использования контекста {/*use-cases-for-context*/} -## Use cases for context {/*use-cases-for-context*/} +* **Изменение темы:** Если ваше приложение позволяет пользователю изменять его внешний вид (например, темный режим), вы можете поместить провайдер контекста в верхней части приложения и использовать этот контекст в компонентах, которым нужно изменять свой внешний вид. +* **Текущий аккаунт:** Многим компонентам может потребоваться информация о текущем вошедшем в систему пользователе. Поместив его в контекст, его удобно читать в любом месте дерева. Некоторые приложения также позволяют работать с несколькими учетными записями одновременно (например, оставлять комментарии от имени другого пользователя). В таких случаях может быть удобно обернуть часть UI во вложенный провайдер с другим текущим значением. +* **Маршрутизация:** Большинство решений для маршрутизации используют внутренний контекст для хранения текущего маршрута. Так каждая ссылка "знает", активна она или нет. Если вы создадите свой собственный маршрутизатор, то, возможно, захотите сделать также. +* **Управление состоянием:** По мере роста вашего приложения вы можете столкнуться с большим количеством состояний в верхней части вашего приложения. Многие дальние компоненты внизу могут захотеть изменить их. Обычно [используется редюсер вместе с контекстом](/learn/scaling-up-with-reducer-and-context), чтобы управлять сложным состоянием и передавать его вниз удаленным компонентам без особых проблем. -* **Theming:** If your app lets the user change its appearance (e.g. dark mode), you can put a context provider at the top of your app, and use that context in components that need to adjust their visual look. -* **Current account:** Many components might need to know the currently logged in user. Putting it in context makes it convenient to read it anywhere in the tree. Some apps also let you operate multiple accounts at the same time (e.g. to leave a comment as a different user). In those cases, it can be convenient to wrap a part of the UI into a nested provider with a different current account value. -* **Routing:** Most routing solutions use context internally to hold the current route. This is how every link "knows" whether it's active or not. If you build your own router, you might want to do it too. -* **Managing state:** As your app grows, you might end up with a lot of state closer to the top of your app. Many distant components below may want to change it. It is common to [use a reducer together with context](/learn/scaling-up-with-reducer-and-context) to manage complex state and pass it down to distant components without too much hassle. - -Context is not limited to static values. If you pass a different value on the next render, React will update all the components reading it below! This is why context is often used in combination with state. +Контекст не ограничивается статическими значениями. Если при следующем рендере вы передадите другое значение, React обновит все компоненты, читающие его ниже! Именно поэтому контекст часто используется в связке с состоянием. -In general, if some information is needed by distant components in different parts of the tree, it's a good indication that context will help you. +В общем, если какая-то информация нужна удаленным компонентам в разных частях дерева, это хороший признак того, что контекст вам может помочь. -* Context lets a component provide some information to the entire tree below it. -* To pass context: - 1. Create and export it with `export const MyContext = createContext(defaultValue)`. - 2. Pass it to the `useContext(MyContext)` Hook to read it in any child component, no matter how deep. - 3. Wrap children into `` to provide it from a parent. -* Context passes through any components in the middle. -* Context lets you write components that "adapt to their surroundings". -* Before you use context, try passing props or passing JSX as `children`. +* Контекст позволяет компоненту предоставлять некоторую информацию всему дереву под ним. +* Чтобы передать контекст: + 1. Создайте и экспортируйте его с помощью `export const MyContext = createContext(defaultValue)`. + 2. Передайте его хуку `useContext(MyContext)`, чтобы прочитать его в любом дочернем компоненте, независимо от его глубины. + 3. Заверните дочерние компоненты в обертку ``, чтобы подтянуть его из родительского компонента. +* Контекст проходит через любые компоненты в середине. +* Контекст позволяет писать компоненты, которые "адаптируются к своему окружению". +* Прежде чем использовать контекст, попробуйте передать пропсы или передать JSX в качестве `children`. -#### Replace prop drilling with context {/*replace-prop-drilling-with-context*/} +#### Замените проп бурение на контекст {/*replace-prop-drilling-with-context*/} -In this example, toggling the checkbox changes the `imageSize` prop passed to each ``. The checkbox state is held in the top-level `App` component, but each `` needs to be aware of it. +В этом примере переключение `checkbox` изменяет проп `imageSize`, передаваемый каждому ``. Состояние элемента `checkbox` хранится в компоненте верхнего уровня `App`, но каждый `` должен знать о нем. -Currently, `App` passes `imageSize` to `List`, which passes it to each `Place`, which passes it to the `PlaceImage`. Remove the `imageSize` prop, and instead pass it from the `App` component directly to `PlaceImage`. +Сейчас `App` передает `imageSize` в `List`, который передает его в каждый `Place`, который передает его в `PlaceImage`. Удалите проп `imageSize`, и вместо этого передавайте его из компонента `App` прямо в `PlaceImage`. -You can declare context in `Context.js`. +Вы можете объявить контекст в файле `Context.js`. @@ -905,7 +905,7 @@ export default function App() { setIsLarge(e.target.checked); }} /> - Use large images + Использовать большие изображения
@@ -959,38 +959,38 @@ function PlaceImage({ place, imageSize }) { ```js src/data.js export const places = [{ id: 0, - name: 'Bo-Kaap in Cape Town, South Africa', - description: 'The tradition of choosing bright colors for houses began in the late 20th century.', + name: 'Бо-Каап в Кейптауне, Южная Африка', + description: 'Традиция выбирать яркие цвета для домов зародилась в конце 20 века.', imageId: 'K9HVAGH' }, { id: 1, - name: 'Rainbow Village in Taichung, Taiwan', - description: 'To save the houses from demolition, Huang Yung-Fu, a local resident, painted all 1,200 of them in 1924.', + name: 'Радужная деревня в Тайчжуне, Тайвань', + description: 'Чтобы спасти дома от сноса, местный житель Хуан Юн Фу в 1924 году раскрасил все 1200 зданий.', imageId: '9EAYZrt' }, { id: 2, - name: 'Macromural de Pachuca, Mexico', - description: 'One of the largest murals in the world covering homes in a hillside neighborhood.', + name: 'Макромурал из Пачуки, Мексика', + description: 'Одна из самых больших фресок в мире, покрывающая дома в районе на холме.', imageId: 'DgXHVwu' }, { id: 3, - name: 'Selarón Staircase in Rio de Janeiro, Brazil', - description: 'This landmark was created by Jorge Selarón, a Chilean-born artist, as a "tribute to the Brazilian people."', + name: 'Лестница Селарона в Рио-де-Жанейро, Бразилия', + description: 'Эта достопримечательность была создана Хорхе Селароном, художником чилийского происхождения, как "дань уважения бразильскому народу".', imageId: 'aeO3rpI' }, { id: 4, - name: 'Burano, Italy', - description: 'The houses are painted following a specific color system dating back to 16th century.', + name: 'Бурано, Италия', + description: 'Дома окрашены по особой системе цветов, восходящей к 16 веку.', imageId: 'kxsph5C' }, { id: 5, - name: 'Chefchaouen, Marocco', - description: 'There are a few theories on why the houses are painted blue, including that the color repels mosquitos or that it symbolizes sky and heaven.', + name: 'Шефчауэн, Марокко', + description: 'Существует несколько теорий, почему дома окрашены в синий цвет, в том числе то, что этот цвет отпугивает комаров или символизирует небо и рай.', imageId: 'rTqKo46' }, { id: 6, - name: 'Gamcheon Culture Village in Busan, South Korea', - description: 'In 2009, the village was converted into a cultural hub by painting the houses and featuring exhibitions and art installations.', + name: 'Культурная деревня Гамчхон в Пусане, Южная Корея', + description: 'В 2009 году деревня была превращена в культурный центр: дома были покрашены, в них были организованы выставки и художественные инсталляции.', imageId: 'ZfQOOzf' }]; ``` @@ -1020,9 +1020,9 @@ li { -Remove `imageSize` prop from all the components. +Удалите проп `imageSize` из всех компонентов. -Create and export `ImageSizeContext` from `Context.js`. Then wrap the List into `` to pass the value down, and `useContext(ImageSizeContext)` to read it in the `PlaceImage`: +Создайте и экспортируйте `ImageSizeContext` из `Context.js`. Затем оберните список провайдером``, чтобы передать значение вниз, и используйте `useContext(ImageSizeContext)`, чтобы прочитать его в `PlaceImage`: @@ -1047,7 +1047,7 @@ export default function App() { setIsLarge(e.target.checked); }} /> - Use large images + Использовать большие изображения
@@ -1098,38 +1098,38 @@ export const ImageSizeContext = createContext(500); ```js src/data.js export const places = [{ id: 0, - name: 'Bo-Kaap in Cape Town, South Africa', - description: 'The tradition of choosing bright colors for houses began in the late 20th century.', + name: 'Бо-Каап в Кейптауне, Южная Африка', + description: 'Традиция выбирать яркие цвета для домов зародилась в конце 20 века.', imageId: 'K9HVAGH' }, { id: 1, - name: 'Rainbow Village in Taichung, Taiwan', - description: 'To save the houses from demolition, Huang Yung-Fu, a local resident, painted all 1,200 of them in 1924.', + name: 'Радужная деревня в Тайчжуне, Тайвань', + description: 'Чтобы спасти дома от сноса, местный житель Хуан Юн Фу в 1924 году раскрасил все 1200 зданий.', imageId: '9EAYZrt' }, { id: 2, - name: 'Macromural de Pachuca, Mexico', - description: 'One of the largest murals in the world covering homes in a hillside neighborhood.', + name: 'Макромурал из Пачуки, Мексика', + description: 'Одна из самых больших фресок в мире, покрывающая дома в районе на холме.', imageId: 'DgXHVwu' }, { id: 3, - name: 'Selarón Staircase in Rio de Janeiro, Brazil', - description: 'This landmark was created by Jorge Selarón, a Chilean-born artist, as a "tribute to the Brazilian people".', + name: 'Лестница Селарона в Рио-де-Жанейро, Бразилия', + description: 'Эта достопримечательность была создана Хорхе Селароном, художником чилийского происхождения, как "дань уважения бразильскому народу".', imageId: 'aeO3rpI' }, { id: 4, - name: 'Burano, Italy', - description: 'The houses are painted following a specific color system dating back to 16th century.', + name: 'Бурано, Италия', + description: 'Дома окрашены по особой системе цветов, восходящей к 16 веку.', imageId: 'kxsph5C' }, { id: 5, - name: 'Chefchaouen, Marocco', - description: 'There are a few theories on why the houses are painted blue, including that the color repels mosquitos or that it symbolizes sky and heaven.', + name: 'Шефчауэн, Марокко', + description: 'Существует несколько теорий, почему дома окрашены в синий цвет, в том числе то, что этот цвет отпугивает комаров или символизирует небо и рай.', imageId: 'rTqKo46' }, { id: 6, - name: 'Gamcheon Culture Village in Busan, South Korea', - description: 'In 2009, the village was converted into a cultural hub by painting the houses and featuring exhibitions and art installations.', + name: 'Культурная деревня Гамчхон в Пусане, Южная Корея', + description: 'В 2009 году деревня была превращена в культурный центр: дома были покрашены, в них были организованы выставки и художественные инсталляции.', imageId: 'ZfQOOzf' }]; ``` @@ -1157,7 +1157,7 @@ li {
-Note how components in the middle don't need to pass `imageSize` anymore. +Обратите внимание, что компонентам в середине больше не нужно передавать `imageSize`.
From 0e2c9da0c324fb99b75246d9669bef5054d00db3 Mon Sep 17 00:00:00 2001 From: abobi Date: Thu, 26 Sep 2024 14:06:57 +0300 Subject: [PATCH 04/16] review and correction --- .../learn/passing-data-deeply-with-context.md | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index 0ca873f7b..68489bef7 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -4,7 +4,7 @@ title: Передача данных через контекст -Обычно вы передаёте информацию от родительского компонента к дочернему с помощью пропсов. Однако такая передача может стать многослойной и неудобной, если необходимо передавать информацию через множество промежуточных компонентов или если многим компонентам в вашем приложении нужна одна и та же информация. *Контекст* позволяет родительскому компоненту передавать информацию любому компоненту в дереве под ним, независимо от глубины и не передавая данные явно через пропсы. +Обычно вы передаёте информацию от родительского компонента к дочернему с помощью пропсов. Однако такая передача может стать многослойной и неудобной, если необходимо передавать информацию через большое количество промежуточных компонентов или если множеству компонентам в вашем приложении нужна одна и та же информация. *Контекст* позволяет родительскому компоненту предоставлять информацию любому компоненту в дереве под ним, независимо от глубины и не передавая данные явно через пропсы. @@ -17,11 +17,11 @@ title: Передача данных через контекст -## Проблема передачи пропса {/*the-problem-with-passing-props*/} +## Проблема передачи пропа {/*the-problem-with-passing-props*/} [Передача пропсов](/learn/passing-props-to-a-component) — это отличный способ явно передать данные через UI дерево компонентам, которые их используют. -Однако передача пропсов может стать муторной, если вам нужно передать их глубоко в дерево, или если многим компонентам нужен один и тот же проп. Ближайший общий предок может находиться далеко от компонентов, которым нужны данные, и [подъём состояния вверх](/learn/sharing-state-between-components) на такую высоту может привести к ситуации, называемой «проп бурение». +Однако передача пропсов может стать муторной, если вам нужно передать их глубоко в дерево или если множеству компонентам нужен один и тот же проп. Ближайший общий предок может находиться далеко от компонентов, которым нужны данные, и [подъём состояния вверх](/learn/sharing-state-between-components) на такую высоту может привести к ситуации, называемой "проп бурение". @@ -38,11 +38,11 @@ title: Передача данных через контекст -Было замечательно, если бы существовал способ «телепортировать» данные в те компоненты дерева, которым они нужны, без передачи пропсов? С помощью функции React контекст это возможно! +А если представить, что у нас есть возможность "телепортировать" данные в те компоненты дерева, которым они нужны, без передачи пропсов? С помощью функции React Контекст это возможно! ## Контекст: альтернатива передачи пропсов {/*context-an-alternative-to-passing-props*/} -Контекст позволяет родительскому компоненту предоставлять данные всему дереву под ним. Существует множество вариантов использования контекста. Вот один из примеров. Рассмотрим компонент `Heading`, который принимает значение `level` для своего размера: +Контекст позволяет родительскому компоненту передавать данные всему дереву под ним. Существует множество вариантов использования контекста. Вот один из примеров. Рассмотрим компонент `Heading`, который принимает значение `level` для своего размера: @@ -190,7 +190,7 @@ export default function Heading({ level, children }) {
``` -Было неплохо, если бы мы могли передавать параметр `level` в компонент `
` и убирать его из ``. Таким образом, мы можем добиться того, чтобы все заголовки в одном разделе имели одинаковый размер: +Более удобным будет передавать параметр `level` в компонент `
` и убирать его из ``. Таким образом, мы можем добиться того, чтобы все заголовки в одном разделе имели одинаковый размер: ```js
@@ -200,13 +200,13 @@ export default function Heading({ level, children }) {
``` -Но как компонент `` может узнать уровень ближайшего к нему `
`? **Это потребует от дочернего компонента какого-то способа «запрашивать» данные откуда-то сверху.** +Но как компонент `` может узнать уровень ближайшего к нему `
`? **Это потребует от дочернего компонента какого-то способа "запрашивать" данные откуда-то сверху.** С помощью одних только пропсов этого не сделать. Здесь на помощь приходит контекст. Вы можете сделать это в три шага: -1. **Создать** контекст. (Вы можете назвать его `LevelContext`, поскольку он предназначен для уровня заголовка). +1. **Создать** контекст. (Можно назвать его `LevelContext`, поскольку он предназначен для уровня заголовка). 2. **Использовать** этот контекст в компоненте, которому нужны данные. (`Heading` будет использовать `LevelContext`). -3. **Предоставить** этот контекст компоненту, определяющему данные. (`Section` предоставит `LevelContext`). +3. **Передать** этот контекст компоненту, определяющему данные. (`Section` передаст `LevelContext`). Контекст позволяет родительскому компоненту — даже удалённому — предоставлять определённые данные всему дереву компонентов внутри него. @@ -327,7 +327,7 @@ export default function Heading({ level, children }) { } ``` -Вместо этого удалите параметр `level` и прочитайте значение из контекста, который вы только что импортировали — `LevelContext`: +Вместо этого удалите проп `level` и добавьте значение из контекста, который вы только что импортировали — `LevelContext`: ```js {2} export default function Heading({ children }) { @@ -336,7 +336,7 @@ export default function Heading({ children }) { } ``` -`useContext` — это хук. Как и `useState`, и `useReducer`, его можно вызывать только непосредственно внутри компонента React (не в циклах или условиях). **`useContext` сообщает React, что компонент `Heading` хочет получить данные из `LevelContext`.** +`useContext` — это хук. Как и `useState` и `useReducer`, его можно вызывать только непосредственно внутри компонента React (не в циклах или условиях). **`useContext` сообщает React, что компонент `Heading` хочет получить данные из `LevelContext`.** Теперь, когда компонент `Heading` больше не имеет свойство `level`, вам не нужно передавать этот проп внутрь `Heading` в ваш JSX как здесь: @@ -444,7 +444,7 @@ export const LevelContext = createContext(1); Обратите внимание, что этот пример еще не совсем рабочий! Все заголовки имеют одинаковый размер, потому что **хоть вы и *используете* контекст, вы еще не *указали* его.** React не знает, где его взять! -Если вы не укажете контекст, React будет использовать значение по умолчанию, которое вы указали на предыдущем шаге. В этом примере вы указали `1` в качестве аргумента для `createContext`, поэтому `useContext(LevelContext)` возвращает `1`, устанавливая для всех заголовков `

` это значение. Давайте исправим эту проблему, заставив каждый `Section` предоставлять свой собственный контекст. +Если вы не укажете контекст, React будет использовать значение по умолчанию, которое вы указали на предыдущем шаге. В этом примере вы указали `1` в качестве аргумента для `createContext`, поэтому `useContext(LevelContext)` возвращает `1`, устанавливая для всех заголовков `

` это значение. Давайте исправим эту проблему, заставив каждый `Section` передать свой собственный контекст. ### Шаг 3: Указать контекст {/*step-3-provide-the-context*/} @@ -460,7 +460,7 @@ export default function Section({ children }) { } ``` -**Оберните их провайдером контекста**, чтобы предоставить им `LevelContext`: +**Оберните их провайдером контекста**, чтобы передать им `LevelContext`: ```js {1,6,8} import { LevelContext } from './LevelContext.js'; @@ -564,13 +564,13 @@ export const LevelContext = createContext(1); -Это тот же результат, что и в исходном коде, но вам не нужно передавать проп `level` каждому компоненту `Heading`! Вместо этого он «выясняет» уровень своего заголовка, запрашивая ближайший `Section` выше: +Это тот же результат, что и в исходном коде, но вам не нужно передавать проп `level` каждому компоненту `Heading`! Вместо этого он "выясняет" уровень своего заголовка, запрашивая ближайший `Section` выше: 1. Вы передаёте проп `level` в `
`. 2. `Section` оборачивает дочерние элементы в ``. 3. `Heading` запрашивает ближайшее значение `LevelContext` с помощью `useContext(LevelContext)`. -## Использование и предоставление контекста в одном и том же компоненте {/*using-and-providing-context-from-the-same-component*/} +## Использование и передача контекста в одинаковых компонентах {/*using-and-providing-context-from-the-same-component*/} В настоящее время вам по-прежнему приходится указывать `level` каждого раздела вручную: @@ -585,7 +585,7 @@ export default function Page() { ... ``` -Так как контекст позволяет считывать информацию из компонента выше, каждый `Section` может считывать `level` из `Section` выше, и автоматически передавать `level + 1` вниз. Вот как это можно сделать: +Так как контекст позволяет считывать информацию из компонента выше, каждый `Section` может считывать `level` из `Section` сверху, и автоматически передавать `level + 1` вниз. Вот как это можно сделать: ```js src/Section.js {5,8} import { useContext } from 'react'; @@ -603,7 +603,7 @@ export default function Section({ children }) { } ``` -Благодаря этому изменению вам не нужно передавать параметр `level` *какому либо* `
` или ``: +Благодаря этому изменению вам не нужно передавать параметр `level` *какому-либо* `
` или ``: @@ -695,7 +695,7 @@ export const LevelContext = createContext(0); -Теперь и `Heading`, и `Section` читают `LevelContext`, чтобы выяснить, насколько "глубоко" они находятся. А `Section` оборачивает свои дочерние элементы в `LevelContext`, чтобы указать, что все, что находится внутри него, находится на более "глубоком" уровне. +Теперь и `Heading`, и `Section` читают `LevelContext`, чтобы выяснить, насколько "глубоко" они находятся. А `Section` оборачивает свои дочерние элементы в LevelContext с целью указать, что всё, что находится внутри, расположено на более "глубоком" уровне. @@ -705,7 +705,7 @@ export const LevelContext = createContext(0); ## Прохождение контекста через промежуточные компоненты {/*context-passes-through-intermediate-components*/} -Вы можете использовать столько компонентов, между предоставляющим контекст, и тем, который его использует компонентами, сколько захотите. Сюда входят как базовые компоненты, такие как `
`, так и те, которые вы можете создать самостоятельно. +Вы можете использовать столько компонентов между передающим контекст и тем, который его использует компонентами, сколько захотите. Сюда входят как базовые компоненты, такие как `
`, так и те, которые вы можете создать самостоятельно. В этом примере один и тот же компонент `Post` (с пунктирной границей) отображается на двух разных уровнях вложенности. Обратите внимание, что `` внутри него автоматически получает свой уровень из ближайшего `
`: @@ -834,11 +834,11 @@ export const LevelContext = createContext(0); Вы не сделали ничего волшебного, чтобы это заработало. `Section` определяет контекст для дерева внутри него, поэтому вы можете поставить `` в любое место, и он будет иметь правильный размер. Попробуйте это в песочнице выше! -**Контекст позволяет вам писать компоненты, которые "адаптируются к своему окружению" и отображаются по-разному в зависимости от того, _где_ (или, другими словами, _в каком контексте_) они отображаются.** +**Контекст позволяет вам писать компоненты, которые "адаптируются к своему окружению" и отображаются по-разному в зависимости от того, _где_ (или другими словами, _в каком контексте_) они отображаются.** -То, как работает контекст, может напомнить вам о [наследовании свойств CSS.](https://developer.mozilla.org/ru/docs/Web/CSS/Inheritance) В нём вы можете указать `color: blue` для `
`, и любой узел DOM внутри него, независимо от его глубины, унаследует этот цвет, если только какой-либо другой узел DOM в середине не переопределит его на `color: green`. Аналогично, в React единственный способ переопределить контекст, поступающий сверху, — это обернуть дочерние элементы в провайдер контекста с другим значением. +То, как работает контекст, может напомнить вам о [наследовании свойств CSS.](https://developer.mozilla.org/ru/docs/Web/CSS/Inheritance) В нём вы можете указать `color: blue` для `
`, и любой узел DOM внутри него, независимо от его глубины, унаследует этот цвет, если только какой-либо другой узел DOM в середине не переопределит его на `color: green`. Аналогично в React. Eдинственный способ переопределить контекст, поступающий сверху, — это обернуть дочерние элементы в провайдер контекста с другим значением. -В CSS разные свойства, такие как `color` и `background-color`, не переопределяют друг друга. Вы можете установить во всех `
` свойство `color` на красный, не влияя на `background-color`. Аналогично, **разные контексты React не переопределяют друг друга.** Каждый контекст, который вы создаете с помощью `createContext()`, полностью отделен от других и связывает компоненты, использующие и предоставляющие *этот конкретный* контекст. Один компонент может использовать или предоставлять множество разных контекстов без проблем. +В CSS разные свойства, такие как `color` и `background-color`, не переопределяют друг друга. Вы можете установить во всех `
` свойство `color` на красный, не влияя на `background-color`. Аналогично, **разные контексты React не переопределяют друг друга.** Каждый контекст, который вы создаете с помощью `createContext()` полностью отделен от других и связывает компоненты, использующие и передающие *этот конкретный* контекст. Один компонент может использовать или передавать множество разных контекстов без проблем. ## Перед использованием контекста {/*before-you-use-context*/} @@ -847,27 +847,27 @@ export const LevelContext = createContext(0); Вот несколько альтернатив, которые нужно рассмотреть, прежде чем использовать контекст: 1. **Начните с [передачи пропсов.](/learn/passing-props-to-a-component)** Если ваши компоненты достаточно простые, то нередко приходится передавать множество пропсов вниз через множество компонентов. Это может показаться трудоёмкой задачей, но так становится ясно, какие компоненты используют те или иные данные! Человек, обслуживающий ваш код, будет рад, что вы сделали поток данных явным с помощью пропсов. -2. **Извлекайте компоненты и [передавайте им JSX как `детям`](/learn/passing-props-to-a-component#passing-jsx-as-children).** Если вы передаете какие-то данные через множество промежуточных компонентов, которые не используют эти данные (а только передают их дальше вниз), это часто означает, что вы забыли извлечь некоторые компоненты на этом пути. Например, вы передаете такие пропсы данных, как `posts`, визуальным компонентам, которые не используют их напрямую, например ``. Вместо этого сделайте так, чтобы `Layout` принимал `children` в качестве проп, и выводил ``. Это уменьшает количество слоев между компонентом, задающим данные, и компонентом, которому они нужны. +2. **Извлекайте компоненты и [передавайте им JSX как `детям`](/learn/passing-props-to-a-component#passing-jsx-as-children).** Если вы передаёте какие-то данные через множество промежуточных компонентов, которые не используют эти данные (а только передают их дальше вниз), это часто означает, что вы забыли извлечь некоторые компоненты на этом пути. Например, вы передаете такие пропсы, как `posts`, визуальным компонентам, которые не используют их напрямую, например, ``. Вместо этого сделайте так, чтобы `Layout` принимал `children` в качестве проп и выводил ``. Это уменьшает количество слоёв между компонентом, задающим данные, и компонентом, которому они нужны. Если ни один из этих подходов вам не подходит, рассмотрите контекст. ## Варианты использования контекста {/*use-cases-for-context*/} * **Изменение темы:** Если ваше приложение позволяет пользователю изменять его внешний вид (например, темный режим), вы можете поместить провайдер контекста в верхней части приложения и использовать этот контекст в компонентах, которым нужно изменять свой внешний вид. -* **Текущий аккаунт:** Многим компонентам может потребоваться информация о текущем вошедшем в систему пользователе. Поместив его в контекст, его удобно читать в любом месте дерева. Некоторые приложения также позволяют работать с несколькими учетными записями одновременно (например, оставлять комментарии от имени другого пользователя). В таких случаях может быть удобно обернуть часть UI во вложенный провайдер с другим текущим значением. +* **Текущий аккаунт:** Многим компонентам может потребоваться информация о текущем вошедшем в систему пользователе. Поместив его в контекст, эту информацию удобно будет читать в любом месте дерева. Некоторые приложения также позволяют работать с несколькими учетными записями одновременно (например оставлять комментарии от имени другого пользователя). В таких случаях может быть удобно обернуть часть UI во вложенный провайдер с другим текущим значением. * **Маршрутизация:** Большинство решений для маршрутизации используют внутренний контекст для хранения текущего маршрута. Так каждая ссылка "знает", активна она или нет. Если вы создадите свой собственный маршрутизатор, то, возможно, захотите сделать также. * **Управление состоянием:** По мере роста вашего приложения вы можете столкнуться с большим количеством состояний в верхней части вашего приложения. Многие дальние компоненты внизу могут захотеть изменить их. Обычно [используется редюсер вместе с контекстом](/learn/scaling-up-with-reducer-and-context), чтобы управлять сложным состоянием и передавать его вниз удаленным компонентам без особых проблем. Контекст не ограничивается статическими значениями. Если при следующем рендере вы передадите другое значение, React обновит все компоненты, читающие его ниже! Именно поэтому контекст часто используется в связке с состоянием. -В общем, если какая-то информация нужна удаленным компонентам в разных частях дерева, это хороший признак того, что контекст вам может помочь. +В общем, если какая-то информация нужна удалённым компонентам в разных частях дерева, это хороший признак того, что контекст вам может помочь. -* Контекст позволяет компоненту предоставлять некоторую информацию всему дереву под ним. +* Контекст позволяет компоненту передавать некоторую информацию всему дереву под ним. * Чтобы передать контекст: 1. Создайте и экспортируйте его с помощью `export const MyContext = createContext(defaultValue)`. - 2. Передайте его хуку `useContext(MyContext)`, чтобы прочитать его в любом дочернем компоненте, независимо от его глубины. + 2. Передайте его хуку `useContext(MyContext)` чтобы прочитать его в любом дочернем компоненте, независимо от его глубины. 3. Заверните дочерние компоненты в обертку ``, чтобы подтянуть его из родительского компонента. * Контекст проходит через любые компоненты в середине. * Контекст позволяет писать компоненты, которые "адаптируются к своему окружению". @@ -881,7 +881,7 @@ export const LevelContext = createContext(0); В этом примере переключение `checkbox` изменяет проп `imageSize`, передаваемый каждому ``. Состояние элемента `checkbox` хранится в компоненте верхнего уровня `App`, но каждый `` должен знать о нем. -Сейчас `App` передает `imageSize` в `List`, который передает его в каждый `Place`, который передает его в `PlaceImage`. Удалите проп `imageSize`, и вместо этого передавайте его из компонента `App` прямо в `PlaceImage`. +Сейчас `App` передает `imageSize` в `List`, который передает его в каждый `Place`, который передает его в `PlaceImage`. Удалите проп `imageSize` и вместо этого передавайте его из компонента `App` прямо в `PlaceImage`. Вы можете объявить контекст в файле `Context.js`. From 72a91989544c86c7a84280865be4d618cc0a43f0 Mon Sep 17 00:00:00 2001 From: abobi Date: Thu, 26 Sep 2024 14:09:15 +0300 Subject: [PATCH 05/16] fixing a bug with the start navigation menu (header is too big, when switching to the header, it does not show up active in the menu) --- src/content/learn/passing-data-deeply-with-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index 68489bef7..dfea97658 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -570,7 +570,7 @@ export const LevelContext = createContext(1); 2. `Section` оборачивает дочерние элементы в ``. 3. `Heading` запрашивает ближайшее значение `LevelContext` с помощью `useContext(LevelContext)`. -## Использование и передача контекста в одинаковых компонентах {/*using-and-providing-context-from-the-same-component*/} +## Использование и передача контекста в компонентах {/*using-and-providing-context-from-the-same-component*/} В настоящее время вам по-прежнему приходится указывать `level` каждого раздела вручную: From dfae230bce72e1a4e406608c1da203f1d91c3f29 Mon Sep 17 00:00:00 2001 From: Nikita Demin <113016827+Pyplee@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:14:09 +0300 Subject: [PATCH 06/16] Commit suggestion - 7 line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit suggestion - 7 line (from "компонентам" to "компонентов") Co-authored-by: Maxim Titov --- src/content/learn/passing-data-deeply-with-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index dfea97658..9461b2121 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -4,7 +4,7 @@ title: Передача данных через контекст -Обычно вы передаёте информацию от родительского компонента к дочернему с помощью пропсов. Однако такая передача может стать многослойной и неудобной, если необходимо передавать информацию через большое количество промежуточных компонентов или если множеству компонентам в вашем приложении нужна одна и та же информация. *Контекст* позволяет родительскому компоненту предоставлять информацию любому компоненту в дереве под ним, независимо от глубины и не передавая данные явно через пропсы. +Обычно вы передаёте информацию от родительского компонента к дочернему с помощью пропсов. Однако такая передача может стать многослойной и неудобной, если необходимо передавать информацию через большое количество промежуточных компонентов или если множеству компонентов в вашем приложении нужна одна и та же информация. *Контекст* позволяет родительскому компоненту предоставлять информацию любому компоненту в дереве под ним, независимо от глубины и не передавая данные явно через пропсы. From 87d664826685d7bd22bacd304699f5ed6774e5f3 Mon Sep 17 00:00:00 2001 From: Nikita Demin <113016827+Pyplee@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:26:58 +0300 Subject: [PATCH 07/16] Commit suggestion - 22 line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit suggestion - 22 line (from "через UI дерево компонентам, которые их используют" to "по дереву компонентов туда, где они используются") Co-authored-by: Maxim Titov --- src/content/learn/passing-data-deeply-with-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index 9461b2121..d7a704fc9 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -19,7 +19,7 @@ title: Передача данных через контекст ## Проблема передачи пропа {/*the-problem-with-passing-props*/} -[Передача пропсов](/learn/passing-props-to-a-component) — это отличный способ явно передать данные через UI дерево компонентам, которые их используют. +[Передача пропсов](/learn/passing-props-to-a-component) — это отличный способ явно передать данные по дереву компонентов туда, где они используются. Однако передача пропсов может стать муторной, если вам нужно передать их глубоко в дерево или если множеству компонентам нужен один и тот же проп. Ближайший общий предок может находиться далеко от компонентов, которым нужны данные, и [подъём состояния вверх](/learn/sharing-state-between-components) на такую высоту может привести к ситуации, называемой "проп бурение". From 36dc2ddf618d15e0fa494cd01304f70045181d4e Mon Sep 17 00:00:00 2001 From: Nikita Demin <113016827+Pyplee@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:28:12 +0300 Subject: [PATCH 08/16] Commit suggestion - 24 line Co-authored-by: Maxim Titov --- src/content/learn/passing-data-deeply-with-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index d7a704fc9..0f7e9709a 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -21,7 +21,7 @@ title: Передача данных через контекст [Передача пропсов](/learn/passing-props-to-a-component) — это отличный способ явно передать данные по дереву компонентов туда, где они используются. -Однако передача пропсов может стать муторной, если вам нужно передать их глубоко в дерево или если множеству компонентам нужен один и тот же проп. Ближайший общий предок может находиться далеко от компонентов, которым нужны данные, и [подъём состояния вверх](/learn/sharing-state-between-components) на такую высоту может привести к ситуации, называемой "проп бурение". +Однако передача пропсов может стать муторной, если вам нужно передать их глубоко в дерево или если множеству компонентов нужен один и тот же проп. Ближайший общий предок может находиться далеко от компонентов, которым нужны данные, и [подъём состояния вверх](/learn/sharing-state-between-components) на такую высоту может привести к ситуации, называемой "бурение пропсов" ("prop drilling"). From b5bb07596943dd04d4436bcaab5583340d00be20 Mon Sep 17 00:00:00 2001 From: Nikita Demin <113016827+Pyplee@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:29:36 +0300 Subject: [PATCH 09/16] Commit suggestion - 41 line Co-authored-by: Maxim Titov --- src/content/learn/passing-data-deeply-with-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index 0f7e9709a..ec9c39bb5 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -38,7 +38,7 @@ title: Передача данных через контекст -А если представить, что у нас есть возможность "телепортировать" данные в те компоненты дерева, которым они нужны, без передачи пропсов? С помощью функции React Контекст это возможно! +А если представить, что у нас есть возможность "телепортировать" данные в те компоненты дерева, которым они нужны, без передачи пропсов? В React это возможно с контекстом! ## Контекст: альтернатива передачи пропсов {/*context-an-alternative-to-passing-props*/} From eaa0a25092a8fe1f5548c271e1fecb68aeb2bb29 Mon Sep 17 00:00:00 2001 From: Nikita Demin <113016827+Pyplee@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:30:21 +0300 Subject: [PATCH 10/16] Commit suggestion - 315 line Co-authored-by: Maxim Titov --- src/content/learn/passing-data-deeply-with-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index ec9c39bb5..7cd81203b 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -312,7 +312,7 @@ export const LevelContext = createContext(1); ### Шаг 2: Использовать контекст {/*step-2-use-the-context*/} -Импортируем хук `useContext` и ваш контекст из React: +Импортируем хук `useContext` из React и ваш контекст: ```js import { useContext } from 'react'; From 4de797cd022dbb978fba93c54575d5858abe61af Mon Sep 17 00:00:00 2001 From: Nikita Demin <113016827+Pyplee@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:31:13 +0300 Subject: [PATCH 11/16] Commit suggestion - 841 line Co-authored-by: Maxim Titov --- src/content/learn/passing-data-deeply-with-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index 7cd81203b..bddcc185e 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -838,7 +838,7 @@ export const LevelContext = createContext(0); То, как работает контекст, может напомнить вам о [наследовании свойств CSS.](https://developer.mozilla.org/ru/docs/Web/CSS/Inheritance) В нём вы можете указать `color: blue` для `
`, и любой узел DOM внутри него, независимо от его глубины, унаследует этот цвет, если только какой-либо другой узел DOM в середине не переопределит его на `color: green`. Аналогично в React. Eдинственный способ переопределить контекст, поступающий сверху, — это обернуть дочерние элементы в провайдер контекста с другим значением. -В CSS разные свойства, такие как `color` и `background-color`, не переопределяют друг друга. Вы можете установить во всех `
` свойство `color` на красный, не влияя на `background-color`. Аналогично, **разные контексты React не переопределяют друг друга.** Каждый контекст, который вы создаете с помощью `createContext()` полностью отделен от других и связывает компоненты, использующие и передающие *этот конкретный* контекст. Один компонент может использовать или передавать множество разных контекстов без проблем. +В CSS разные свойства, такие как `color` и `background-color`, не переопределяют друг друга. Вы можете установить во всех `
` свойство `color` на красный, не влияя на `background-color`. Аналогично, **разные контексты React не переопределяют друг друга.** Каждый контекст, который вы создаёте с помощью `createContext()` полностью отделён от других и связывает компоненты, использующие и передающие *этот конкретный* контекст. Один компонент может использовать или передавать множество разных контекстов без проблем. ## Перед использованием контекста {/*before-you-use-context*/} From 67d2a6eccf834eb822b6b986da9d8f7d5f896cf9 Mon Sep 17 00:00:00 2001 From: Nikita Demin <113016827+Pyplee@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:31:47 +0300 Subject: [PATCH 12/16] Commit suggestion - 850 line Co-authored-by: Maxim Titov --- src/content/learn/passing-data-deeply-with-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index bddcc185e..d84fb342b 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -847,7 +847,7 @@ export const LevelContext = createContext(0); Вот несколько альтернатив, которые нужно рассмотреть, прежде чем использовать контекст: 1. **Начните с [передачи пропсов.](/learn/passing-props-to-a-component)** Если ваши компоненты достаточно простые, то нередко приходится передавать множество пропсов вниз через множество компонентов. Это может показаться трудоёмкой задачей, но так становится ясно, какие компоненты используют те или иные данные! Человек, обслуживающий ваш код, будет рад, что вы сделали поток данных явным с помощью пропсов. -2. **Извлекайте компоненты и [передавайте им JSX как `детям`](/learn/passing-props-to-a-component#passing-jsx-as-children).** Если вы передаёте какие-то данные через множество промежуточных компонентов, которые не используют эти данные (а только передают их дальше вниз), это часто означает, что вы забыли извлечь некоторые компоненты на этом пути. Например, вы передаете такие пропсы, как `posts`, визуальным компонентам, которые не используют их напрямую, например, ``. Вместо этого сделайте так, чтобы `Layout` принимал `children` в качестве проп и выводил ``. Это уменьшает количество слоёв между компонентом, задающим данные, и компонентом, которому они нужны. +2. **Извлекайте компоненты и [передавайте им JSX как `детям`](/learn/passing-props-to-a-component#passing-jsx-as-children).** Если вы передаёте какие-то данные через множество промежуточных компонентов, которые не используют эти данные (а только передают их дальше вниз), это часто означает, что вы забыли извлечь некоторые компоненты на этом пути. Например, вы передаете такие пропсы, как `posts`, визуальным компонентам, которые не используют их напрямую, например, ``. Вместо этого сделайте так, чтобы `Layout` принимал `children` в качестве пропа и выводил ``. Это уменьшает количество слоёв между компонентом, задающим данные, и компонентом, которому они нужны. Если ни один из этих подходов вам не подходит, рассмотрите контекст. From 2fd2e8c8fdcbe10a8f0fc90b7ba92033e5ab6b15 Mon Sep 17 00:00:00 2001 From: Nikita Demin <113016827+Pyplee@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:58:29 +0300 Subject: [PATCH 13/16] Commit suggestion - 35 line Co-authored-by: Maxim Titov --- src/content/learn/passing-data-deeply-with-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index d84fb342b..54f79ebc3 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -32,7 +32,7 @@ title: Передача данных через контекст -Проп бурение +Бурение пропсов From c44d76ddb2d973e20d40570f7c66ea11fa896789 Mon Sep 17 00:00:00 2001 From: abobi Date: Fri, 29 Nov 2024 19:08:18 +0300 Subject: [PATCH 14/16] corrections have been made about the drilling of props --- src/content/learn/passing-data-deeply-with-context.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index 54f79ebc3..0159c9e46 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -10,7 +10,7 @@ title: Передача данных через контекст -- Что такое "проп бурение" +- Что такое "prop drilling" (бурение пропсов) - Как заменить повторяющуюся передачу пропсов - Рядовые случаи использования контекста - Альтернативы контекста @@ -877,7 +877,7 @@ export const LevelContext = createContext(0); -#### Замените проп бурение на контекст {/*replace-prop-drilling-with-context*/} +#### Замените "prop drilling" (бурение пропсов) на контекст {/*replace-prop-drilling-with-context*/} В этом примере переключение `checkbox` изменяет проп `imageSize`, передаваемый каждому ``. Состояние элемента `checkbox` хранится в компоненте верхнего уровня `App`, но каждый `` должен знать о нем. From d610ddd19f8cbbd240357c1b6d1460dca4d634a3 Mon Sep 17 00:00:00 2001 From: abobi Date: Fri, 29 Nov 2024 19:46:14 +0300 Subject: [PATCH 15/16] translate attribute - alt on diagrams --- src/content/learn/passing-data-deeply-with-context.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index 0159c9e46..4966b8b58 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -25,12 +25,12 @@ title: Передача данных через контекст - + Подъём состояния - + Бурение пропсов @@ -212,13 +212,13 @@ export default function Heading({ level, children }) { - + Использование контекста с детьми вблизи - + Использование контекста с детьми на расстоянии From 943d7e1902c3b9e1c107b3af504f5841955603c0 Mon Sep 17 00:00:00 2001 From: abobi Date: Fri, 29 Nov 2024 19:55:15 +0300 Subject: [PATCH 16/16] =?UTF-8?q?check=20and=20correcting=20symbol=20'?= =?UTF-8?q?=D1=91'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/content/learn/passing-data-deeply-with-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index 4966b8b58..a5dec743b 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -879,7 +879,7 @@ export const LevelContext = createContext(0); #### Замените "prop drilling" (бурение пропсов) на контекст {/*replace-prop-drilling-with-context*/} -В этом примере переключение `checkbox` изменяет проп `imageSize`, передаваемый каждому ``. Состояние элемента `checkbox` хранится в компоненте верхнего уровня `App`, но каждый `` должен знать о нем. +В этом примере переключение `checkbox` изменяет проп `imageSize`, передаваемый каждому ``. Состояние элемента `checkbox` хранится в компоненте верхнего уровня `App`, но каждый `` должен знать о нём. Сейчас `App` передает `imageSize` в `List`, который передает его в каждый `Place`, который передает его в `PlaceImage`. Удалите проп `imageSize` и вместо этого передавайте его из компонента `App` прямо в `PlaceImage`.