TriggerScope
Стабильный · с 0.1.0
Передаёт id скоупа потомкам. Вызовы useCondition и useAction внутри этого поддерева регистрируются со скоупом, и только триггеры, объявленные с таким же scope в createTrigger(...), их увидят. Рантайм, инспектор, планировщик и middleware остаются общими — TriggerScope это более лёгкое внутрирантаймовое разделение по сравнению с <TriggerRuntimeProvider>.
Используй его, когда один рантайм — это правильно, но нужно, чтобы две половины дерева регистрировали независимых провайдеров для одного и того же условия или действия.
import { TriggerScope } from '@triggery/react';
Сигнатура
Заголовок раздела «Сигнатура»function TriggerScope(props: TriggerScopeProps): JSX.Element;
type TriggerScopeProps = {
readonly id: string;
readonly children: ReactNode;
};| Проп | Тип | Обязательный | Описание |
|---|---|---|---|
id | string | да | Id скоупа. Должен совпадать с полем scope триггера, чтобы связаться. |
children | ReactNode | да | Поддерево, в котором регистрации помечаются id. |
Примеры
Заголовок раздела «Примеры»Два инстанса чата на одной странице
Заголовок раздела «Два инстанса чата на одной странице»import { createTrigger } from '@triggery/core';
import { TriggerScope, useAction, useCondition, useEvent } from '@triggery/react';
const messageTrigger = createTrigger<{
events: { 'new-message': { author: string; text: string } };
conditions: { activeChannelId: string };
actions: { showToast: { title: string } };
}>({
id: 'chat:new-message',
scope: 'chat',
events: ['new-message'],
required: ['activeChannelId'],
handler({ event, conditions, actions }) {
if (event.payload.author === conditions.activeChannelId) return;
actions.showToast?.({ title: event.payload.author });
},
});
function ChatA() {
useCondition(messageTrigger, 'activeChannelId', () => 'a', []);
useAction(messageTrigger, 'showToast', t => console.log('toast A', t.title));
return null;
}
function ChatB() {
useCondition(messageTrigger, 'activeChannelId', () => 'b', []);
useAction(messageTrigger, 'showToast', t => console.log('toast B', t.title));
return null;
}
function Page() {
return (
<>
<TriggerScope id="chat">
<ChatA />
</TriggerScope>
<TriggerScope id="chat">
{/* Second scope — registrations from ChatB would override ChatA's
but they're in a different boundary. Use distinct ids if you want
truly independent buckets. */}
<ChatB />
</TriggerScope>
</>
);
}Независимые скоупы для двух инстансов триггеров
Заголовок раздела «Независимые скоупы для двух инстансов триггеров»import { createTrigger } from '@triggery/core';
import { TriggerScope, useCondition } from '@triggery/react';
const triggerLeft = createTrigger<{
events: { ping: void };
conditions: { value: number };
}>({ id: 'left', scope: 'left', events: ['ping'], required: ['value'], handler() {} });
const triggerRight = createTrigger<{
events: { ping: void };
conditions: { value: number };
}>({ id: 'right', scope: 'right', events: ['ping'], required: ['value'], handler() {} });
function Layout() {
return (
<>
<TriggerScope id="left">
<Provider t={triggerLeft} v={1} />
</TriggerScope>
<TriggerScope id="right">
<Provider t={triggerRight} v={2} />
</TriggerScope>
</>
);
}
function Provider({ t, v }: { t: ReturnType<typeof createTrigger>; v: number }) {
useCondition(t, 'value', () => v, [v]);
return null;
}Вложенные скоупы
Заголовок раздела «Вложенные скоупы»Внутренний id побеждает для всего, что внутри него:
import { TriggerScope } from '@triggery/react';
<TriggerScope id="outer">
{/* registrations here tagged "outer" */}
<TriggerScope id="inner">
{/* registrations here tagged "inner" */}
</TriggerScope>
</TriggerScope>Замечания
Заголовок раздела «Замечания»См. также
Заголовок раздела «См. также» TriggerRuntimeProvider Тяжёлая изоляция — отдельный рантайм на поддерево.
createTrigger Где ты объявляешь поле `scope`.
useCondition Регистрации внутри скоупа наследуют его id.
Руководство по скоупам Паттерны для multi-instance UI.