Skip to content

Commit

Permalink
docs: Update Russian translation (#1226)
Browse files Browse the repository at this point in the history
* Update ru/guide/v10/api-reference.md

* Update ru/guide/v10/context.md

* Update ru/guide/v10/differences-to-react.md

* Update ru/guide/v10/forms.md

* Update ru/guide/v10/hooks.md

* Update ru/guide/v10/no-build-workflows.md

* Update ru/guide/v10/refs.md

* Update config.json
  • Loading branch information
dragomano authored Jan 18, 2025
1 parent f2bdc36 commit be9de0a
Show file tree
Hide file tree
Showing 8 changed files with 687 additions and 203 deletions.
2 changes: 1 addition & 1 deletion content/ru/guide/v10/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ render(

Предоставляет способ ссылки на элемент или компонент после его визуализации.

Дополнительную информацию см. в [документации по ссылкам](/guide/v10/refs#createref).
Дополнительную информацию см. в [документации по рефам](/guide/v10/refs#создание-рефа).

## Fragment

Expand Down
172 changes: 139 additions & 33 deletions content/ru/guide/v10/context.md
Original file line number Diff line number Diff line change
@@ -1,78 +1,184 @@
---
name: Контекст
description: 'Контекст позволяет передавать параметры через промежуточные компоненты. В этом документе описывается как новый, так и старый API'
description: 'Контекст позволяет передавать параметры через промежуточные компоненты. В этой документации описывается как новый, так и старый API'
---

# Контекст

Контекст позволяет передавать значение дочернему компоненту в глубине дерева, не пропуская его через все последующие компоненты с помощью `props`. Очень популярным вариантом такого использования является тематическое оформление. В двух словах контекст можно представить как способ выполнения обновлений в стиле `pub-sub` в Preact.
Контекст — это способ передачи данных через дерево компонентов без необходимости передавать их через каждый промежуточный компонент с помощью пропсов. Проще говоря, он позволяет компонентам в любой части иерархии подписываться на значение и получать уведомления о его изменениях, обеспечивая обновления в стиле pub-sub для Preact.

Существует два различных способа использования контекста: Через новый API `createContext` и старый API контекста. Разница между ними заключается в том, что старый вариант не может обновить дочерний компонент, когда компонент между ними прерывает рендеринг через `shouldComponentUpdate`. Поэтому мы настоятельно рекомендуем всегда использовать `createContext`.
Не редкость сталкиваться с ситуациями, когда значение из компонента-прародителя (или выше) нужно передать дочернему компоненту, часто без необходимости в промежуточном компоненте. Этот процесс передачи пропсов часто называют «проп-дриллингом», и он может быть громоздким, подверженным ошибкам и просто утомительным, особенно по мере роста приложения и необходимости передавать больше значений через большее количество слоёв. Это одна из ключевых проблем, которую контекст стремится решить, предоставляя способ для дочернего компонента подписаться на значение, находящееся выше в дереве компонентов, получая доступ к значению без его передачи в качестве пропса.

В Preact есть два способа использования контекста: через новый API `createContext` и устаревший context API. В настоящее время существует очень мало причин использовать устаревший API, но он документирован здесь для полноты.

---

<div><toc></toc></div>

---

## createContext
## Современный Context API

### Создание контекста

Чтобы создать новый контекст, мы используем функцию `createContext`. Эта функция принимает начальное состояние в качестве аргумента и возвращает объект с двумя свойствами компонентов: `Provider`, чтобы сделать контекст доступным для потомков, и `Consumer`, чтобы получить доступ к значению контекста (в основном в классовых компонентах).

```jsx
import { createContext } from "preact";

export const Theme = createContext("light");
export const User = createContext({ name: "Guest" });
export const Locale = createContext(null);
```

### Настройка провайдера

После того как мы создали контекст, мы должны сделать его доступным для потомков, используя компонент `Provider`. Провайдеру необходимо передать пропс `value`, представляющий начальное значение контекста.

> Начальное значение, установленное с помощью `createContext`, используется только в отсутствие `Provider` выше потребителя в дереве. Это может быть полезно для тестирования компонентов в изоляции, так как позволяет избежать необходимости создания обёртки `Provider` вокруг вашего компонента.
```jsx
import { createContext } from "preact";

export const Theme = createContext("light");

function App() {
return (
<Theme.Provider value="dark">
<SomeComponent />
</Theme.Provider>
);
}
```

> **Совет:** Вы можете иметь несколько провайдеров одного и того же контекста в вашем приложении, но будет использоваться только ближайший к потребителю.
### Использование контекста

Сначала нам необходимо создать объект контекста, который мы сможем передавать по кругу. Это делается с помощью функции `createContext(initialValue)`. Он возвращает компонент `Provider`, который используется для установки значения контекста, и компонент `Consumer`, который извлекает значение из контекста.
Существует два способа потребления контекста, в значительной степени в зависимости от предпочитаемого вами стиля компонентов: `Consumer` (классовые компоненты) и хук `useContext` (функциональные компоненты/хуки).

Аргумент `initialValue` используется только в том случае, если у контекста нет соответствующего `Provider` над ним в дереве. Это может быть полезно для изолированного тестирования компонентов, поскольку позволяет избежать необходимости создания оборачивающего `Provider`.
<tab-group tabstring="Consumer, useContext">

```jsx
// --repl
import { render, createContext } from 'preact';
import { render, createContext } from "preact";

const SomeComponent = (props) => props.children;
const SomeComponent = props => props.children;
// --repl-before
const Theme = createContext('light');
const ThemePrimary = createContext("#673ab8");

function ThemedButton(props) {
function ThemedButton() {
return (
<Theme.Consumer>
{(theme) => {
return (
<button {...props} class={'btn ' + theme}>
Переключить тему
</button>
);
}}
</Theme.Consumer>
<ThemePrimary.Consumer>
{theme => <button style={{ background: theme }}>Переключить тему</button>}
</ThemePrimary.Consumer>
);
}

function App() {
return (
<Theme.Provider value='dark'>
<ThemePrimary.Provider value="#8f61e1">
<SomeComponent>
<ThemedButton />
</SomeComponent>
</Theme.Provider>
</ThemePrimary.Provider>
);
}
// --repl-after
render(<App />, document.getElementById("app"));
```

```jsx
// --repl
import { render, createContext } from "preact";
import { useContext } from "preact/hooks";

const SomeComponent = props => props.children;
// --repl-before
const ThemePrimary = createContext("#673ab8");

function ThemedButton() {
const theme = useContext(ThemePrimary);
return <button style={{ background: theme }}>Переключить тему</button>;
}

function App() {
return (
<ThemePrimary.Provider value="#8f61e1">
<SomeComponent>
<ThemedButton />
</SomeComponent>
</ThemePrimary.Provider>
);
}
// --repl-after
render(<App />, document.getElementById("app"));
```

</tab-group>

### Обновление контекста

Статические значения могут быть полезны, но чаще всего мы хотим иметь возможность динамически обновлять значение контекста. Для этого мы используем стандартные механизмы состояния компонентов:

```jsx
// --repl
import { render, createContext } from "preact";
import { useContext, useState } from "preact/hooks";

const SomeComponent = props => props.children;
// --repl-before
const ThemePrimary = createContext(null);

function ThemedButton() {
const { theme } = useContext(ThemePrimary);
return <button style={{ background: theme }}>Переключить тему</button>;
}

function ThemePicker() {
const { theme, setTheme } = useContext(ThemePrimary);
return (
<input
type="color"
value={theme}
onChange={e => setTheme(e.currentTarget.value)}
/>
);
}

function App() {
const [theme, setTheme] = useState("#673ab8");
return (
<ThemePrimary.Provider value={{ theme, setTheme }}>
<SomeComponent>
<ThemedButton />
{" - "}
<ThemePicker />
</SomeComponent>
</ThemePrimary.Provider>
);
}
// --repl-after
render(<App />, document.getElementById('app'));
render(<App />, document.getElementById("app"));
```

> Более простой способ использовать контекст — использовать хук [useContext](/guide/v10/hooks#usecontext).
## Устаревший Context API

## Устаревший API контекста
Этот API считается устаревшим и должен быть избегаем в новом коде, так как у него есть известные проблемы, и он существует только для обеспечения обратной совместимости.

Мы включаем устаревший API в основном из соображений обратной совместимости. Он был заменен API `createContext`. У устаревшего API есть известные проблемы, такие как блокировка обновлений, если между ними есть компоненты, которые возвращают false в `shouldComponentUpdate`. Если вам всё же нужно его использовать, продолжайте читать.
Одно из ключевых отличий этого API от нового заключается в том, что этот API не может обновить дочерний компонент, когда компонент между дочерним компонентом и провайдером отменяет рендеринг с помощью `shouldComponentUpdate`. Когда это происходит, дочерний компонент **не получит** обновлённое значение контекста, что часто приводит к разрыву (часть интерфейса использует новое значение, а часть — старое).

Чтобы передать пользовательскую переменную через контекст, компонент должен иметь метод `getChildContext`. Там вы возвращаете новые значения, которые хотите сохранить в контексте. Доступ к контексту можно получить через второй аргумент в функциональных компонентах или через `this.context` в компоненте на основе класса.
Чтобы передать значение через контекст, компонент должен иметь метод `getChildContext`, возвращающий предполагаемое значение контекста. Потомки могут получить доступ к контексту через второй аргумент в функциональных компонентах или `this.context` в классовых компонентах.

```jsx
// --repl
import { render } from 'preact';
import { render } from "preact";

const SomeOtherComponent = (props) => props.children;
const SomeOtherComponent = props => props.children;
// --repl-before
function ThemedButton(props, context) {
function ThemedButton(_props, context) {
return (
<button {...props} class={'btn ' + context.theme}>
<button style={{ background: context.theme }}>
Переключить тему
</button>
);
Expand All @@ -81,8 +187,8 @@ function ThemedButton(props, context) {
class App extends Component {
getChildContext() {
return {
theme: 'light',
};
theme: "#673ab8"
}
}

render() {
Expand All @@ -96,5 +202,5 @@ class App extends Component {
}
}
// --repl-after
render(<App />, document.getElementById('app'));
render(<App />, document.getElementById("app"));
```
2 changes: 1 addition & 1 deletion content/ru/guide/v10/differences-to-react.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Preact не претендует на то, чтобы быть повторно

Как для preact, так и для [preact/compat] совместимость версий измеряется по отношению к _текущим_ и _предыдущим_ основным выпускам React. Когда команда React анонсирует новые функции, они могут быть добавлены в ядро ​​Preact, если это имеет смысл с учетом [целей проекта][Project Goals]. Это довольно демократичный процесс, постоянно развивающийся посредством дискуссий и решений, принимаемых открыто, с использованием вопросов и запросов на включение.

> Таким образом, веб-сайт и документация отражают React от «15.x» до «17.x» при обсуждении совместимости или сравнении.
> Таким образом, сайт и документация отражают версии React с `15.x` по `17.x`, с некоторыми дополнениями из `18.x` и `19.x`, когда речь идет о совместимости или сравнении.
## Отладочные сообщения и ошибки

Expand Down
Loading

0 comments on commit be9de0a

Please sign in to comment.