Skip to content
GitHubXDiscord

@triggery/redux

Read a Redux store from a Triggery condition without subscribing the component to re-renders. Works with vanilla Redux and @reduxjs/toolkit — the hook only calls store.getState() at fire time.

npm bundle

pnpm add @triggery/core @triggery/react @triggery/redux redux

Peer deps: react >= 18.0.0, redux ^4 || ^5. @reduxjs/toolkit re-exports the same Store shape and works out of the box.

ExportPurpose
useReduxCondition(trigger, name, store, selector)Register a Redux-backed condition. The component is not subscribed to the store.
import { configureStore } from '@reduxjs/toolkit';
import { createTrigger } from '@triggery/core';
import { useReduxCondition } from '@triggery/redux';
import { rootReducer } from './rootReducer';

const store = configureStore({ reducer: rootReducer });

type State = ReturnType<typeof store.getState>;
type Settings = State['settings'];

const messageTrigger = createTrigger<{
  events: { 'new-message': { text: string } };
  conditions: { settings: Settings };
  actions: { showToast: { body: string } };
}>({
  id: 'message-received',
  events: ['new-message'],
  required: ['settings'],
  handler({ event, conditions, actions }) {
    if (!conditions.settings.notifications) return;
    actions.showToast?.({ body: event.payload.text });
  },
});

function SettingsBridge() {
  useReduxCondition(messageTrigger, 'settings', store, (s) => s.settings);
  return null;
}

Triggery is pull-only: the selector runs only when a trigger fires, not on every dispatch. The hook does not subscribe the component to the store — dispatches never re-render the bridge component. If a separate component needs the same slice in its JSX, use useSelector from react-redux alongside.

useReduxCondition<T, S, K>(
  trigger: Trigger<S>,
  name: K,
  store: { getState(): T },
  selector: (state: T) => ConditionMap<S>[K],
): void