Skip to content

Commit 385daf5

Browse files
authored
docs: Update Russian translation (#1382)
* Update ru/guide/v10/signals.md * Update ru/guide/v11/signals.md
1 parent b3833be commit 385daf5

2 files changed

Lines changed: 248 additions & 248 deletions

File tree

content/ru/guide/v10/signals.md

Lines changed: 124 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ function createAppState() {
249249
}
250250
```
251251

252-
> :bulb: Совет: Обратите внимание, что мы сознательно не включили сюда функции `addTodo()` и `removeTodo(todo)`. Отделение данных от функций, которые их изменяют, часто помогает упростить архитектуру приложения. Для получения более подробной информации ознакомьтесь со статьёй [дизайн, ориентированный на данные](https://habr.com/ru/articles/321106/).
252+
> :bulb: Совет: Обратите внимание, что мы сознательно не включили сюда функции `addTodo()` и `removeTodo(todo)`. Отделение данных от функций, которые их изменяют, часто помогает упростить архитектуру приложения. Для получения более подробной информации ознакомьтесь со статьёй [дизайн, ориентированный на данные](https://www.dataorienteddesign.com/dodbook/).
253253
>
254254
> Теперь мы можем передать состояние нашего приложения todo в качестве параметра при рендеринге:
255255
@@ -543,6 +543,128 @@ console.log(counter.count.value); // 6
543543

544544
Подробнее о том, как использовать модели в ваших компонентах, и полная справочная информация по API — см. [API моделей](#createmodelfactory) в разделе API ниже.
545545

546+
#### Ключевые возможности
547+
548+
- **Аргументы фабрики**: Фабричные функции могут принимать аргументы для инициализации, что делает модели повторно используемыми с разными конфигурациями.
549+
- **Автоматическая пакетная обработка**: Все методы, возвращаемые из фабрики, автоматически оборачиваются как действия, поэтому обновления состояния внутри них группируются в пакет и не отслеживаются.
550+
- **Автоматическая очистка эффектов**: Эффекты, созданные при построении модели, захватываются и автоматически удаляются при уничтожении модели через `Symbol.dispose`.
551+
- **Компонуемые модели**: Модели естественно компонуются — эффекты из вложенных моделей захватываются родительской и удаляются вместе с ней при уничтожении родителя.
552+
553+
#### Композиция моделей
554+
555+
Модели можно вкладывать друг в друга. При уничтожении родительской модели все эффекты из вложенных моделей автоматически очищаются:
556+
557+
```js
558+
const TodoItemModel = createModel((text) => {
559+
const completed = signal(false);
560+
561+
return {
562+
text,
563+
completed,
564+
toggle() {
565+
completed.value = !completed.value;
566+
}
567+
};
568+
});
569+
570+
const TodoListModel = createModel(() => {
571+
const items = signal([]);
572+
573+
return {
574+
items,
575+
addTodo(text) {
576+
const todo = new TodoItemModel(text);
577+
items.value = [...items.value, todo];
578+
},
579+
removeTodo(todo) {
580+
items.value = items.value.filter(t => t !== todo);
581+
todo[Symbol.dispose]();
582+
}
583+
};
584+
});
585+
586+
const todoList = new TodoListModel();
587+
todoList.addTodo('Купить продукты');
588+
todoList.addTodo('Выгулять собаку');
589+
590+
// Уничтожение родительской модели также очищает все эффекты вложенных моделей
591+
todoList[Symbol.dispose]();
592+
```
593+
594+
### Рекомендуемые паттерны
595+
596+
#### Явный паттерн ReadonlySignal
597+
598+
Для лучшей инкапсуляции объявляйте интерфейс вашей модели явно и используйте `ReadonlySignal` для сигналов, которые должны изменяться только через экшены:
599+
600+
```ts
601+
import { signal, computed, createModel, ReadonlySignal } from '@preact/signals';
602+
603+
interface Counter {
604+
count: ReadonlySignal<number>;
605+
doubled: ReadonlySignal<number>;
606+
increment(): void;
607+
decrement(): void;
608+
}
609+
610+
const CounterModel = createModel<Counter>(() => {
611+
const count = signal(0);
612+
const doubled = computed(() => count.value * 2);
613+
614+
return {
615+
count,
616+
doubled,
617+
increment() {
618+
count.value++;
619+
},
620+
decrement() {
621+
count.value--;
622+
}
623+
};
624+
});
625+
626+
const counter = new CounterModel();
627+
counter.increment(); // OK
628+
counter.count.value = 10; // Ошибка TypeScript: Cannot assign to 'value'
629+
```
630+
631+
#### Пользовательская логика уничтожения
632+
633+
Если вашей модели требуется пользовательская логика очистки, не связанная с сигналами (например, закрытие WebSocket-соединений), используйте эффект без зависимостей, который возвращает функцию очистки:
634+
635+
```js
636+
const WebSocketModel = createModel((url) => {
637+
const messages = signal([]);
638+
const ws = new WebSocket(url);
639+
640+
ws.onmessage = (e) => {
641+
messages.value = [...messages.value, e.data];
642+
};
643+
644+
// Этот эффект выполняется один раз; его очистка запускается при уничтожении
645+
effect(() => {
646+
return () => {
647+
ws.close();
648+
};
649+
});
650+
651+
return {
652+
messages,
653+
send(message) {
654+
ws.send(message);
655+
}
656+
};
657+
});
658+
659+
const chat = new WebSocketModel('wss://example.com/chat');
660+
chat.send('Привет!');
661+
662+
// Закрывает WebSocket-соединение при уничтожении
663+
chat[Symbol.dispose]();
664+
```
665+
666+
Этот паттерн аналогичен `useEffect(() => { return cleanup }, [])` в React и гарантирует, что очистка происходит автоматически при композиции моделей — родительским моделям не нужно знать о функциях уничтожения вложенных моделей.
667+
546668
## API
547669

548670
В этом разделе представлен обзор API сигналов. Он призван стать кратким справочником для людей, которые уже знают, как использовать сигналы, и нуждаются в напоминании о том, что доступно.
@@ -686,54 +808,6 @@ console.log(counter.doubled.value); // 12
686808
counter[Symbol.dispose]();
687809
```
688810

689-
#### Ключевые возможности
690-
691-
- **Аргументы фабрики**: Фабричные функции могут принимать аргументы для инициализации, что делает модели повторно используемыми с разными конфигурациями.
692-
- **Автоматическая пакетная обработка**: Все методы, возвращаемые из фабрики, автоматически оборачиваются как действия, поэтому обновления состояния внутри них группируются в пакет и не отслеживаются.
693-
- **Автоматическая очистка эффектов**: Эффекты, созданные при построении модели, захватываются и автоматически удаляются при уничтожении модели через `Symbol.dispose`.
694-
- **Компонуемые модели**: Модели естественно компонуются — эффекты из вложенных моделей захватываются родительской и удаляются вместе с ней при уничтожении родителя.
695-
696-
#### Композиция моделей
697-
698-
Модели можно вкладывать друг в друга. При уничтожении родительской модели все эффекты из вложенных моделей автоматически очищаются:
699-
700-
```js
701-
const TodoItemModel = createModel((text) => {
702-
const completed = signal(false);
703-
704-
return {
705-
text,
706-
completed,
707-
toggle() {
708-
completed.value = !completed.value;
709-
}
710-
};
711-
});
712-
713-
const TodoListModel = createModel(() => {
714-
const items = signal([]);
715-
716-
return {
717-
items,
718-
addTodo(text) {
719-
const todo = new TodoItemModel(text);
720-
items.value = [...items.value, todo];
721-
},
722-
removeTodo(todo) {
723-
items.value = items.value.filter(t => t !== todo);
724-
todo[Symbol.dispose]();
725-
}
726-
};
727-
});
728-
729-
const todoList = new TodoListModel();
730-
todoList.addTodo('Купить продукты');
731-
todoList.addTodo('Выгулять собаку');
732-
733-
// Уничтожение родительской модели также очищает все эффекты вложенных моделей
734-
todoList[Symbol.dispose]();
735-
```
736-
737811
### action(fn)
738812

739813
Функция `action(fn)` оборачивает функцию для выполнения в пакетном и неотслеживаемом контексте. Это полезно, когда нужно создать самостоятельные действия вне модели:
@@ -798,80 +872,6 @@ function Counter({ initialValue }) {
798872
}
799873
```
800874

801-
### Рекомендуемые паттерны
802-
803-
#### Явный паттерн ReadonlySignal
804-
805-
Для лучшей инкапсуляции объявляйте интерфейс вашей модели явно и используйте `ReadonlySignal` для сигналов, которые должны изменяться только через экшены:
806-
807-
```ts
808-
import { signal, computed, createModel, ReadonlySignal } from '@preact/signals';
809-
810-
interface Counter {
811-
count: ReadonlySignal<number>;
812-
doubled: ReadonlySignal<number>;
813-
increment(): void;
814-
decrement(): void;
815-
}
816-
817-
const CounterModel = createModel<Counter>(() => {
818-
const count = signal(0);
819-
const doubled = computed(() => count.value * 2);
820-
821-
return {
822-
count,
823-
doubled,
824-
increment() {
825-
count.value++;
826-
},
827-
decrement() {
828-
count.value--;
829-
}
830-
};
831-
});
832-
833-
const counter = new CounterModel();
834-
counter.increment(); // OK
835-
counter.count.value = 10; // Ошибка TypeScript: Cannot assign to 'value'
836-
```
837-
838-
#### Пользовательская логика уничтожения
839-
840-
Если вашей модели требуется пользовательская логика очистки, не связанная с сигналами (например, закрытие WebSocket-соединений), используйте эффект без зависимостей, который возвращает функцию очистки:
841-
842-
```js
843-
const WebSocketModel = createModel((url) => {
844-
const messages = signal([]);
845-
const ws = new WebSocket(url);
846-
847-
ws.onmessage = (e) => {
848-
messages.value = [...messages.value, e.data];
849-
};
850-
851-
// Этот эффект выполняется один раз; его очистка запускается при уничтожении
852-
effect(() => {
853-
return () => {
854-
ws.close();
855-
};
856-
});
857-
858-
return {
859-
messages,
860-
send(message) {
861-
ws.send(message);
862-
}
863-
};
864-
});
865-
866-
const chat = new WebSocketModel('wss://example.com/chat');
867-
chat.send('Привет!');
868-
869-
// Закрывает WebSocket-соединение при уничтожении
870-
chat[Symbol.dispose]();
871-
```
872-
873-
Этот паттерн аналогичен `useEffect(() => { return cleanup }, [])` в React и гарантирует, что очистка происходит автоматически при композиции моделей — родительским моделям не нужно знать о функциях уничтожения вложенных моделей.
874-
875875
## Вспомогательные компоненты и хуки
876876

877877
Начиная с версии v2.1.0, пакет `@preact/signals/utils` предоставляет дополнительные вспомогательные компоненты и хуки, упрощающие работу с сигналами.
@@ -969,4 +969,4 @@ function Component() {
969969
- **[Signals Debug](https://github.com/preactjs/signals/blob/main/packages/debug)** — Инструмент разработки, который предоставляет подробный вывод в консоль об обновлениях сигналов, выполнении эффектов и пересчётах вычисляемых значений.
970970
- **[Signals DevTools](https://github.com/preactjs/signals/blob/main/packages/devtools-ui)** — Визуальный интерфейс DevTools для отладки и визуализации Preact Signals в реальном времени. Его можно встроить прямо на страницу для демонстраций или интегрировать в собственные инструменты.
971971
972-
> **Примечание:** Это инструменты, независимые от фреймворка, из библиотеки Signals. Хотя они отлично работают с Preact, они не являются специфичными именно для Preact.
972+
> **Примечание:** Это инструменты, независимые от фреймворка, из библиотеки Signals. Хотя они отлично работают с Preact, они не являются специфичными именно для Preact.

0 commit comments

Comments
 (0)