diff --git a/content/ru/guide/v10/api-reference.md b/content/ru/guide/v10/api-reference.md index 1f8e04688..924927a95 100644 --- a/content/ru/guide/v10/api-reference.md +++ b/content/ru/guide/v10/api-reference.md @@ -201,7 +201,7 @@ render( Предоставляет способ ссылки на элемент или компонент после его визуализации. -Дополнительную информацию см. в [документации по ссылкам](/guide/v10/refs#createref). +Дополнительную информацию см. в [документации по рефам](/guide/v10/refs#создание-рефа). ## Fragment diff --git a/content/ru/guide/v10/context.md b/content/ru/guide/v10/context.md index e60bbad12..da18e7726 100644 --- a/content/ru/guide/v10/context.md +++ b/content/ru/guide/v10/context.md @@ -1,13 +1,15 @@ --- name: Контекст -description: 'Контекст позволяет передавать параметры через промежуточные компоненты. В этом документе описывается как новый, так и старый API' +description: 'Контекст позволяет передавать параметры через промежуточные компоненты. В этой документации описывается как новый, так и старый API' --- # Контекст -Контекст позволяет передавать значение дочернему компоненту в глубине дерева, не пропуская его через все последующие компоненты с помощью `props`. Очень популярным вариантом такого использования является тематическое оформление. В двух словах контекст можно представить как способ выполнения обновлений в стиле `pub-sub` в Preact. +Контекст — это способ передачи данных через дерево компонентов без необходимости передавать их через каждый промежуточный компонент с помощью пропсов. Проще говоря, он позволяет компонентам в любой части иерархии подписываться на значение и получать уведомления о его изменениях, обеспечивая обновления в стиле pub-sub для Preact. -Существует два различных способа использования контекста: Через новый API `createContext` и старый API контекста. Разница между ними заключается в том, что старый вариант не может обновить дочерний компонент, когда компонент между ними прерывает рендеринг через `shouldComponentUpdate`. Поэтому мы настоятельно рекомендуем всегда использовать `createContext`. +Не редкость сталкиваться с ситуациями, когда значение из компонента-прародителя (или выше) нужно передать дочернему компоненту, часто без необходимости в промежуточном компоненте. Этот процесс передачи пропсов часто называют «проп-дриллингом», и он может быть громоздким, подверженным ошибкам и просто утомительным, особенно по мере роста приложения и необходимости передавать больше значений через большее количество слоёв. Это одна из ключевых проблем, которую контекст стремится решить, предоставляя способ для дочернего компонента подписаться на значение, находящееся выше в дереве компонентов, получая доступ к значению без его передачи в качестве пропса. + +В Preact есть два способа использования контекста: через новый API `createContext` и устаревший context API. В настоящее время существует очень мало причин использовать устаревший API, но он документирован здесь для полноты. --- @@ -15,64 +17,168 @@ description: 'Контекст позволяет передавать пара --- -## 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 ( + + + + ); +} +``` + +> **Совет:** Вы можете иметь несколько провайдеров одного и того же контекста в вашем приложении, но будет использоваться только ближайший к потребителю. + +### Использование контекста -Сначала нам необходимо создать объект контекста, который мы сможем передавать по кругу. Это делается с помощью функции `createContext(initialValue)`. Он возвращает компонент `Provider`, который используется для установки значения контекста, и компонент `Consumer`, который извлекает значение из контекста. +Существует два способа потребления контекста, в значительной степени в зависимости от предпочитаемого вами стиля компонентов: `Consumer` (классовые компоненты) и хук `useContext` (функциональные компоненты/хуки). -Аргумент `initialValue` используется только в том случае, если у контекста нет соответствующего `Provider` над ним в дереве. Это может быть полезно для изолированного тестирования компонентов, поскольку позволяет избежать необходимости создания оборачивающего `Provider`. + ```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) => { - return ( - - ); - }} - + + {theme => } + ); } function App() { return ( - + - + + ); +} +// --repl-after +render(, 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 ; +} + +function App() { + return ( + + + + + + ); +} +// --repl-after +render(, document.getElementById("app")); +``` + + + +### Обновление контекста + +Статические значения могут быть полезны, но чаще всего мы хотим иметь возможность динамически обновлять значение контекста. Для этого мы используем стандартные механизмы состояния компонентов: + +```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 ; +} + +function ThemePicker() { + const { theme, setTheme } = useContext(ThemePrimary); + return ( + setTheme(e.currentTarget.value)} + /> + ); +} + +function App() { + const [theme, setTheme] = useState("#673ab8"); + return ( + + + + {" - "} + + + ); } // --repl-after -render(, document.getElementById('app')); +render(, 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 ( - ); @@ -81,8 +187,8 @@ function ThemedButton(props, context) { class App extends Component { getChildContext() { return { - theme: 'light', - }; + theme: "#673ab8" + } } render() { @@ -96,5 +202,5 @@ class App extends Component { } } // --repl-after -render(, document.getElementById('app')); +render(, document.getElementById("app")); ``` diff --git a/content/ru/guide/v10/differences-to-react.md b/content/ru/guide/v10/differences-to-react.md index a4110a72d..6350e71ae 100644 --- a/content/ru/guide/v10/differences-to-react.md +++ b/content/ru/guide/v10/differences-to-react.md @@ -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`, когда речь идет о совместимости или сравнении. ## Отладочные сообщения и ошибки diff --git a/content/ru/guide/v10/forms.md b/content/ru/guide/v10/forms.md index 70daa3f8a..2b4a02920 100644 --- a/content/ru/guide/v10/forms.md +++ b/content/ru/guide/v10/forms.md @@ -1,13 +1,11 @@ --- name: Формы -description: 'Как создавать потрясающие формы в Preact, которые работают где угодно.' +description: 'Формы и элементы управления формами позволяют собирать вводимые пользователем данные в вашем приложении и являются основным строительным блоком большинства веб-приложений.' --- # Формы -Формы в Preact работают почти так же, как и в HTML. Вы визуализируете элемент управления и прикрепляете к нему прослушиватель событий. - -Основное отличие заключается в том, что в большинстве случаев `значением` (`value`) управляет не узел DOM, а Preact. +Формы в Preact работают так же, как и в HTML и JavaScript: вы отображаете элементы управления, прикрепляете обработчики событий и отправляете информацию. --- @@ -15,159 +13,404 @@ description: 'Как создавать потрясающие формы в Pre --- -## Контролируемые и неконтролируемые компоненты +## Основные элементы управления формами + +Часто вам потребуется собирать вводимые пользователем данные в вашем приложении, и здесь на помощь приходят элементы ``, `