Skip to main content

Redux Actions and Selectors

Introduction

React POS keeps all of its runtime data in a single Redux store. When you build a prompt in a customer project you will need to read data out of that store (the prompt's data, the values the user has typed, the POS terminal, the current resolution) and write to it (send an event back to the process, show the keyboard, update the basket view).

This document is a reference for the two things you use to do that:

  • Selectors - functions that read a value out of the store.
  • Actions - functions you dispatch to change the store or to send something to the server.

Only two of the Enactor packages declare actions and selectors:

PackageOwnsNamespace in the store
@enactor/redux-javascript-bridgeEverything that talks to the Enactor server - prompts, view data, events, messages, expressionsstate.enactorBridge
@enactor/react-base-componentsLocal UI state - form inputs, keyboard, basket view, resolution, notificationsstate.enactorPos

@enactor/react-pos, @enactor/self-checkout, @enactor/react-crm and @enactor/react-inventory do not declare their own actions or selectors. They only compose these two. So whenever you need a selector or an action, it comes from one of the two packages above.

info

If you are new to how a prompt connects to the store, read the Using Redux Store tutorial first. It walks through connect, defaultMapStateToProps and sendEvent step by step. This document is the lookup reference you come back to afterwards.

For the base components that consume this data (ConnectedTextInput, SaleShellContainer, MenuContainer and so on), see How to Customize React POS.


The store at a glance

The store has exactly two top-level namespaces. Every selector reads from one of them.

state.enactorBridge - server data

SliceWhat it holds
promptsThe prompts currently open, keyed by promptInstanceId. This is where promptData lives.
viewDataServer view data by name - POS terminal, location, base currency, attributes
statusBridge connection status
configConnection config and locale
messagesLoaded message bases (translations)
expressionsCache of resolved expressions
resourcesCache of resolved resources (images, message files)
menusMenu state per prompt instance
historyPreviously displayed prompts
translationsTranslation-mode groups
stylesheetDataServer-driven stylesheets
attachmentsCaptured and previewed attachments
deviceSupportPer-prompt device (scanner) configuration
connectionsCache of outbound connection requests
remoteRoutes, remoteComponentMaps, uiExtensionsUI extension (module federation) data
configScreen, viewEvents, uiRecorderConfig overlay, registered view events, UI recorder

state.enactorPos - local UI state

SliceWhat it holds
inputsThe value cache - every value the user has typed, per prompt, plus focus and cursor state
promptUIStateBasket items, scroll position, selected index, keyboard/keypad visibility
keyboardKeyboard type, default input mode, layouts
resolutionCurrent device breakpoint (deviceType)
backgroundActive background variant
userNotifications, posNotifications, userTaskCountNotification lists and task count
transactionProcessingStatusValueEndpoint / transaction processing status
autoAdvanceAuto-advance index and active flag
debugDebug panel visibility
tip

You can see this whole tree live in the browser using the Redux DevTools extension. Navigate to enactorBridge -> prompts -> pagesMap -> <PageID> -> pageResponse to find the current prompt's data.


Quick start - the standard prompt pattern

Most prompts never need to reach for an individual selector. defaultMapStateToProps and defaultMapDispatchToProps already give you the standard set, and you only add selectors on top when you need something extra.

import { connect } from "react-redux";
import {
defaultMapStateToProps,
defaultMapDispatchToProps,
getValueCache
} from "@enactor/react-base-components";
import { getPageState } from "@enactor/redux-javascript-bridge";

const mapStateToProps = (state, ownProps) => {
const { promptUrl } = getPageState(state, ownProps);

return {
...defaultMapStateToProps(state, ownProps), // promptData, promptUrl, processId,
// promptInstanceId, promptTimeout, locale
valueCache: getValueCache(state, promptUrl) // the values the user has typed
};
};

const mapDispatchToProps = (dispatch, ownProps) => {
return {
...defaultMapDispatchToProps(dispatch, ownProps) // gives you eventHandlers.sendEvent
};
};

export default connect(mapStateToProps, mapDispatchToProps)(MyPrompt);

Inside the component:

const MyPrompt = props => {
const { promptData, valueCache, eventHandlers } = props;

const handleOK = () => {
eventHandlers.sendEvent("OKPressed", { customerId: valueCache.customerId });
};

return <>{/* ... */}</>;
};

Selectors reference

All selectors take the whole store state as their first argument, unless a note says otherwise.

Prompt and page

Import from @enactor/redux-javascript-bridge.

These are the selectors you will use most. getPageState is the one nearly every prompt uses.

SelectorArgumentsReturns
getPageState(state, ownProps)A flat object: { ...ownProps, windowType, processId, promptUrl, promptData, promptInstanceId }. The standard shape for mapStateToProps.
getPromptState(state, ownProps)The full page object for ownProps.promptInstanceId. Falls back to the topmost prompt if no id is given, and to a history entry if the prompt has already closed.
getDefaultPageState(state)The first page in the store. Use when you have no ownProps to work with.
selectPages(state)Array of all currently open pages.
selectPagesMap(state)The same pages as an object keyed by promptInstanceId.
selectPage(state, promptInstanceId)One page. With no id, returns the topmost (last) page.
selectPageByPromptUrl(state, promptUrl)The first open page matching that prompt URL.
selectActivePromptIds(state)Array of the active promptInstanceId values.
selectControllerInstanceId(state)The promptInstanceId of the prompt currently driving the process.
const { promptUrl, promptData, processId } = getPageState(state, ownProps);
note

Prefer getPageState over reading state.enactorBridge.prompts directly. When several prompts are open at once (a modal over a base prompt, for example), getPageState resolves the right one from ownProps.promptInstanceId for you.

Form inputs and the value cache

Import from @enactor/react-base-components.

Everything the user types into a ConnectedTextInput, ConnectedSelectInput or ConnectedCheckboxInput lands in the value cache, keyed by prompt URL and then by input name.

SelectorArgumentsReturns
getValueCache(state, promptUrl)Flat { inputName: value } for the prompt. This is what you send back to the process.
getDisplayValueFromValueCache(state, promptUrl)Flat { inputName: displayValue } - the formatted text as shown on screen.
getInput(state, promptUrl, inputName)The full value container for one input: value, display value, cursor position, formatter, disabled flag.
getDefaultValueFromValueCache(state, promptUrl)The raw value-container map for the prompt.
getInputsForPromptUrl(state, promptUrl)The whole inputs slice with its value cache narrowed to one prompt. Useful when a component needs focus and cursor state too.
getFocussedValue(state)The value container of the input that currently has focus, or {}.
getPromptInputName(state)The name of the prompt's implicit single input.
const valueCache = getValueCache(state, promptUrl);
const { forename, surname, excluded } = valueCache;
note

value is the raw value you send to the server. displayValue is the formatted version the user sees (for example 12/05/24 for a date input, or £15.00 for a currency input). Always send value, never displayValue.

POS terminal, location and view data

Import from @enactor/redux-javascript-bridge.

View data is data the server publishes by name, independently of any prompt. It survives across prompts, so it is where terminal- and store-level information lives.

SelectorArgumentsReturns
getViewDataItem(state, dataName)Any view data item by name. The general-purpose accessor.
getViewData(state)The whole viewData slice.
posTerminalSelector(state)The POS terminal record.
locationSelector(state)The location (store) record.
baseCurrencySelector(state)The base currency.
getPosTerminalCurrencyFromViewData(state)The terminal's currency ID as a string, "" if not set.
getLocationCurrencyFromViewData(state)The location's currency ID as a string, "" if not set.
getPosTerminalScannerPrefixFromViewData(state)The keyboard-wedge scanner address, or null.
selectPosTerminalAttributes(state)The terminal attribute map.
selectPosTerminalAttribute(state, name, defaultValue)One terminal attribute, or defaultValue.
selectLocationAttributes(state)The location attribute map.
selectLocationAttribute(state, name, defaultValue)One location attribute, or defaultValue.
selectIsScoInPosMode(state)true when Self Checkout is in operator (POS) mode. Drives operator vs customer view.
selectPosInCustomerView(pages)true when the POS is showing the customer view. Takes the pages array, not state - pass selectPages(state).
// Prefer the specific selector when one exists
const currencyId = getPosTerminalCurrencyFromViewData(state);

// Fall back to the generic accessor for anything else
const myData = getViewDataItem(state, "enactor.pos.someCustomViewData");
note

View data has to be requested before it appears in the store. If a selector returns undefined, dispatch the matching fetch... action first - see Fetching view data.

caution

selectPosTerminalAttribute and selectLocationAttribute return defaultValue for any falsy stored value, including 0, "" and false. If you store numeric or boolean attributes, read the whole map with selectPosTerminalAttributes / selectLocationAttributes and check the key yourself.

UI state - keyboard, resolution, basket

Import from @enactor/react-base-components.

SelectorArgumentsReturns
getCurrentDeviceResolution(state)The current breakpoint. Compare against the exported MOBILE_DEVICE, TAB_DEVICE, DESKTOP_DEVICE constants.
getResolution(state)The whole resolution slice.
getIsKeyboardVisible(state)true when the on-screen keyboard is showing.
getKeyboardType(state)The active keyboard variant (alpha / caps / shift).
getDefaultInputMode(state)Native keyboard vs application keyboard.
getKeyboardLayouts(state)The configured keyboard layouts.
getPromptUIState(state)Basket items, scroll position, selected index and device visibility together.
getPreviousBasketItems(state)The basket as it was before the last update - use it to diff for line-add animation.
getAutoAdvanceDetails(state)The auto-advance index and active flag.
getCurrentBackground(state)The active background variant.
getBridgeLocale(state)The locale as a string such as "en-GB", or undefined if not yet resolved.
import { getCurrentDeviceResolution, MOBILE_DEVICE } from "@enactor/react-base-components";

const isMobile = getCurrentDeviceResolution(state) === MOBILE_DEVICE;

Notifications and task count

Import from @enactor/react-base-components.

SelectorArgumentsReturns
selectUserNotifications(state)All user notifications.
selectUnacknowledgedUserNotifications(state)Only notifications whose status is not ACKNOWLEDGED.
selectPosNotifications(state)POS notification messages.
selectEndPointStatusNotifications(state)Endpoint / transaction processing status.
selectUserTaskCount(state)The outstanding user task count.
caution

selectUnacknowledgedUserNotifications filters on every call, so it returns a new array each time. Used directly in mapStateToProps it will re-render the component on every dispatch. If that matters, select the full list and filter inside the component with useMemo.

Messages, expressions and resources

Import from @enactor/redux-javascript-bridge.

In most cases you should use the ResolvableMessage and Image components instead of these selectors - they handle the fetch and the caching for you. Reach for the selectors only when you need the resolved value in logic rather than in JSX.

SelectorArgumentsReturns
messageSelector(state, messageBase, messageId)One translated message string.
expressionResultSelector(state, expression, expressionData)The cached result of a resolved expression. expressionData defaults to "Default".
memoizedExpressionResultSelector(state, expression, expressionData)The same lookup, memoized. Prefer this one in mapStateToProps.
getResource(state, resourceURI)A resolved resource entry with its content and status.
createResourceKey(resourceURI)Builds the cache key used by getResource.
stylesheetDataSelector(state, dataName)One resolved server-driven stylesheet.
styleSheetLoadingSelector(state, dataName)Whether stylesheets are still loading.
note

styleSheetLoadingSelector returns a single global loading flag - the dataName argument is accepted but does not narrow the result. Treat it as "are any stylesheets still loading".

Menus and history

Import from @enactor/redux-javascript-bridge.

SelectorArgumentsReturns
selectMenuState(state)Menu state for every prompt instance.
selectMenu(state, promptInstanceId)Menu state for one prompt instance.
selectHistoryEntries(state)Previously displayed prompts, oldest first.
selectHistoryEntriesCount(state)How many history entries there are.
selectHistoryEntry(state, promptInstanceId)One archived prompt.
note

MenuContainer reads menu state for you. Use these selectors only when you are building custom menu chrome - for example a breadcrumb showing the current folder path.

Config, devices and connections

Import from @enactor/redux-javascript-bridge.

SelectorArgumentsReturns
getEnactorConfig(state)The whole connection config.
getEnactorBridgeLocale(state)The locale as { language, country }.
selectDeviceSupport(state)Array of per-prompt device support entries.
selectIsCameraScannerEnabledForPrompt(state, promptUrl)true when the prompt declares camera scanner support.
isScannerEnabled(state, promptUrl)Alias of the selector above, kept for older call sites.
selectIsCameraScannerEnabled(state)Currently always returns true, to match the Android and iOS behaviour. Use the per-prompt selector instead.
connectionsSelector(state)The whole outbound request cache.
connectionSelector(state, requestId)The response payload for one request, or {}.

UI extensions

Import from @enactor/redux-javascript-bridge. Relevant only if you are building a federated POS extension.

SelectorArgumentsReturns
selectUIExtensions(state)Array of loaded remote extensions.
selectUIExtensionsLoaded(state)true once the extension manifest has loaded.
uiExtensionsSelector(state)The whole uiExtensions slice.
selectRemoteRoutes(state)The federated route table. Merged over the static routes.
selectRemoteRoutesLoaded(state)true once remote routes are ready.
selectRemoteComponentMaps(state)The federated component maps.
selectRemoteComponentMapsLoaded(state)true once remote component maps are ready.
selectUiRecorderEnabled(state)true when the UI activity recorder is on.
info

Nothing renders until both selectRemoteRoutesLoaded and selectRemoteComponentMapsLoaded are true. If your extension's prompts never appear, check these two first.

Container helpers

Import from @enactor/react-base-components. These are not slice selectors, but they are what most connected prompts actually call.

HelperArgumentsReturns
defaultMapStateToProps(state, ownProps)The standard prompt props: promptData, promptUrl, processId, promptInstanceId, promptTimeout, locale.
defaultMapDispatchToProps(dispatch, ownProps)The standard dispatchers, including eventHandlers.sendEvent.
getAllPromptsData(state)promptData merged across every open prompt.
getPosState(state)The whole enactorPos namespace.
getCurrencyId(state)The terminal currency, falling back to the location currency. Use this for FormattedAmount and currency formatters.
getMaxIndexInList(pageState)The last selectable index, for keyboard list navigation.
isPaginatedList(list)Whether a list is paginated.

Actions reference

Dispatch these from mapDispatchToProps (or with the useDispatch hook). Most already come wired up through defaultMapDispatchToProps, so check there before adding your own.

Sending events to the process

Import from @enactor/redux-javascript-bridge. This is how your prompt talks back to the application process.

ActionArgumentsWhat it does
sendEvent(pageEvent, promptData, cmpProps)The general-purpose outbound event.
sendPageEvent(pageEvent, promptData)Sends a prompt-scoped PageEvent.
sendDeviceEvent(eventName, scannerData, target)Sends scanner or peripheral input. eventName defaults to "ScannerData".
sendViewEvent(viewEventName, viewEventData)Sends a view-level event, not tied to a prompt.
promptDataChanged(dataName, dataValue, promptInstanceId)Updates a single field on an open prompt's promptData.
setHistoryPrompt(promptInstanceId, pageState)Records a prompt into history.

In practice you rarely call sendEvent directly. defaultMapDispatchToProps wraps it as eventHandlers.sendEvent(eventName, data):

const { eventHandlers: { sendEvent } } = props;

sendEvent("OKPressed", { customerId: "12345" });

The event name must match an event configured on the Prompt State in the application process.

Form inputs

Import from @enactor/react-base-components.

The Connected* input components already dispatch these for you. You only need them when building a custom input, or when setting a value programmatically.

ActionArgumentsWhat it does
sendEventWithInput(...)Reads the value cache and submits it as a PageEvent. The standard "user pressed Enter" path.
sendEventWithMultipleInputs(...)The same, for a multi-field form submit.
keyPressAction({ ... })Handles a key press: applies formatting, moves the cursor, may trigger auto-advance. Takes a single object argument.
pointAction({ ... })Sets focus and caret position from a pointer event.
formChangeAction({ ... })Records a native input change and takes focus.
formChangeActionWithoutFocus({ promptUrls, name, value })Sets a value without stealing focus. Use this for programmatic updates.
inputStateCleanup({ promptUrls, keepLastFocusElement })Clears the value cache for prompts that have closed.
formatterInitialize(promptUrl, name, formatterConfig, minimumUnitValue)Registers an amount / date / time formatter for one field.
setPromptInputName(promptInputName)Names the prompt's implicit single input.
initiateSelection / completeSelection()Open and close the text-selection guard.
tip

To set an input value from code without disturbing the user's focus, use formChangeActionWithoutFocus. Using formChangeAction will pull focus onto that field, which is usually not what you want mid-flow.

Fetching view data

Import from @enactor/redux-javascript-bridge.

ActionArgumentsWhat it does
fetchViewData(viewDataName)Requests one named view datum.
fetchViewDataSet(viewDataNames)Requests several at once. Prefer this over multiple single calls.
fetchPosTerminal()Requests the POS terminal record.
fetchPosTerminalAttributes()Requests the terminal attribute map.
fetchLocation()Requests the location record.
fetchLocationAttributes()Requests the location attribute map.
fetchBaseCurrency()Requests the base currency.
fetchPosMode()Requests the SCO POS-mode flag read by selectIsScoInPosMode.
registerForViewData(viewDataName)Subscribes so the store updates whenever the server pushes that datum.
viewDataChanged(dataName, dataValue)Applies an inbound view data update. Normally dispatched by the bridge, not by you.
// Ask for what you need once, when the prompt mounts
useEffect(() => {
dispatch(fetchViewDataSet(["posTerminal", "location"]));
}, []);
note

fetch... requests the value once. registerForViewData keeps it up to date. If your prompt needs to react to a value changing while it is open, register for it rather than fetching it.

Expressions, resources and messages

Import from @enactor/redux-javascript-bridge.

ActionArgumentsWhat it does
resolveExpression(expression, expressionData, lifespan)Resolves an Enactor expression on the server and caches the result. lifespan controls how long the cache entry lives.
clearExpression(expression, expressionData)Drops one cached expression result.
resolveResource(...)Resolves a resource such as an image or message file, with in-flight de-duplication.
markResourceDirty(resourceType, resourceURI)Forces the resource to be refetched next time it is read.
markResourceInUse(resourceType, resourceURI)Pins a resource against cache eviction.
loadMessageResource(messageResourceId)Loads a message base.
clearCache(duration)Purges the bridge cache. Defaults to 10000 ms.
note

Prefer the resolveExpression action over the older resolveExpressionPromise helper in @enactor/react-base-components - that one is marked deprecated.

UI state

Import from @enactor/react-base-components.

ActionArgumentsWhat it does
showKeyboard / hideKeyboard / toggleKeyboard()Show, hide or toggle the on-screen keyboard.
showNumPad / hideNumPad / toggleNumPad()Show, hide or toggle the numeric keypad.
triggerBasketUpdate(basketItems)Updates the basket view. Keeps the previous list so the UI can animate new lines.
triggerBasketScrollUpdate(basketScrollPosition)Updates the basket scroll position.
triggerSelectedIndexUpdate(selectedIndex)Updates the selected row in a selection prompt.
triggerAutoAdvance(updatedIndex)Moves focus to the next field after a full-length entry.
deactivateAutoAdvance()Turns auto-advance off.
changeBackground(background)Sets the background. Use the exported DEFAULT_BACKGROUND, EMPTY_BACKGROUND, SIGN_ON_BACKGROUND, SALE_BACKGROUND constants.
resolutionChanged(resolution)Updates the device breakpoint. Dispatched by the resolution listener.
showDebug / hideDebug / toggleDebug()Control the debug panel.

Keyboard configuration

Import from @enactor/react-base-components.

ActionArgumentsWhat it does
changeKeyboardType(keyboardType)Switches the keyboard variant (alpha, caps, shift).
changeDefaultInputMode(defaultInputMode)Sets the default input mode.
useNativeKeyboard()Switches to the device's native keyboard.
useApplicationKeyboard()Switches to the POS on-screen keyboard.

Notifications and task count

Import from @enactor/react-base-components.

ActionArgumentsWhat it does
loadUserNotifications()Subscribes to user notifications.
addUserNotifications(userNotifications)Sends new notifications up to the server.
acknowledgeUserNotifications(notificationIds)Acknowledges notifications on the server.
clearUserNotifications()Clears the local notification list.
loadPosNotifications()Subscribes to POS notification messages.
loadEndPointNotifications()Subscribes to endpoint status.
loadUserTaskCount()Subscribes to the user task count.
note

addUserNotifications and acknowledgeUserNotifications do not change the store directly - the server owns notification state, and the slice updates when the server pushes the change back. Do not expect the list to update synchronously.

Menus

Import from @enactor/react-base-components.

ActionArgumentsWhat it does
menuEvent(menuItem, menuState, promptInstanceId)Handles a menu button click. Folders resolve their expressions and descend, back pops a level, and buttons build event data from the value cache and submit it.
resolveMenuExpressions(menuFolder)Resolves the labels and visibility of a menu folder. Returns a promise.
note

MenuContainer already dispatches menuEvent for you. Call it yourself only when building fully custom menu chrome.

Config, translation, attachments and extensions

Import from @enactor/redux-javascript-bridge.

ActionArgumentsWhat it does
connectToBridge()Opens the WebSocket and registers all handlers. Called once by the app shell.
updateConnectionConfig(config)Updates the connection config and persists it to cookies.
updateLocale()Reads the locale from the bridge into the store.
showConfigScreen / hideConfigScreen()Show and hide the config screen.
showConfigOverlay / hideConfigOverlay()Show and hide the config overlay.
enableDeviceSupport(deviceSupport)Registers per-prompt device (scanner) configuration.
enableTranslationMode / disableTranslationMode()Turn translation mode on and off.
registerTranslationGroup(...)Registers a translatable group.
captureResource(messageBase)Opens the native attachment capture flow.
uploadPreviewSelectedResource()Uploads the selected attachment to the server.
resetAttachments()Clears captured attachments.
fetchUIExtensions()Loads the UI extension manifest.
setRemoteRoutes / addRemoteRoutes(routes)Replace or merge the federated route table.
setRemoteComponentMaps / addRemoteComponentMaps(componentMaps)Replace or merge the federated component maps.
sendCapturedEvent(feature, scenario, events)Ships a recorded scenario from the UI recorder.
setUiRecorderEnabled(enabled)Turns the UI recorder on and off.

Common recipes

Read the values the user has typed

import { getValueCache } from "@enactor/react-base-components";
import { getPageState } from "@enactor/redux-javascript-bridge";

const mapStateToProps = (state, ownProps) => {
const { promptUrl } = getPageState(state, ownProps);
return {
...defaultMapStateToProps(state, ownProps),
valueCache: getValueCache(state, promptUrl)
};
};

Format an amount in the terminal's currency

import { getCurrencyId, FormattedAmount } from "@enactor/react-base-components";

// in mapStateToProps
currencyId: getCurrencyId(state)

// in the component
<FormattedAmount amount={total} currencyId={props.currencyId} />

Render differently on mobile

import {
getCurrentDeviceResolution,
MOBILE_DEVICE
} from "@enactor/react-base-components";

// in mapStateToProps
isMobile: getCurrentDeviceResolution(state) === MOBILE_DEVICE

Read a terminal attribute

import { selectPosTerminalAttribute } from "@enactor/redux-javascript-bridge";

// in mapStateToProps
allowOverride: selectPosTerminalAttribute(state, "allowPriceOverride", "false")

Set an input value from code

import { formChangeActionWithoutFocus } from "@enactor/react-base-components";

const mapDispatchToProps = (dispatch, ownProps) => ({
...defaultMapDispatchToProps(dispatch, ownProps),
setInputValue: (promptUrl, name, value) =>
dispatch(formChangeActionWithoutFocus({ promptUrls: [promptUrl], name, value }))
});

Show the on-screen keyboard when a prompt opens

import { showKeyboard } from "@enactor/react-base-components";

const mapDispatchToProps = dispatch => ({
showKeyboard: () => dispatch(showKeyboard())
});

// in the component
useEffect(() => { props.showKeyboard(); }, []);

Things to watch out for

Some selector names exist twice

@enactor/react-base-components exports selectors at two levels:

  • From the package root - these take the whole store state. Always import these.
  • From inside individual reducer files - these take only their own slice.

getInput, getValueCache, getFocussedValue, getPromptInputName, getPromptUIState, getPreviousBasketItems, getIsKeyboardVisible, getAutoAdvanceDetails and getCurrentDeviceResolution all exist in both forms.

// Correct
import { getValueCache } from "@enactor/react-base-components";

// Wrong - this version expects the inputs slice, not the whole state,
// and will silently return undefined
import { getValueCache } from "@enactor/react-base-components/src/reducers/inputs/inputsReducer";

Passing the wrong argument does not throw - you simply get undefined. If a selector returns undefined and the data is clearly there in the DevTools tree, check your import path first.

Selectors are not memoized

There is only one memoized selector in the toolkit (memoizedExpressionResultSelector). Everything else is a plain function, and several build a new object or array on every call - getValueCache, getDisplayValueFromValueCache, getPageState and selectUnacknowledgedUserNotifications among them.

Used in mapStateToProps, a selector that returns a fresh object defeats connect's shallow comparison and the component re-renders on every dispatch. For most prompts this is harmless. If you hit a performance problem in a busy prompt such as the basket, derive the value with useMemo inside the component instead of computing it in mapStateToProps.

Two selectors take a slice, not the whole state

selectTranslationGroup and selectTransationsForPrompt (note the spelling) expect the translations slice rather than the root state. They are only relevant to translation mode.

selectPosInCustomerView takes the pages array - pass it selectPages(state).

Not everything in the source is importable

Some selectors and actions are exported from their own file but are not re-exported from the package, so you cannot import them in a customer project:

  • From @enactor/redux-javascript-bridge: viewClosed, sendViewPage, removePrompt, clearPage, resolveLocalResource, resolveResourceWithExpression, markMessageResourceDirty, enableCameraScanner, captureAttachment, previewAttachment, setPreviewButton, stylesheetDataChanged, pageUrlSelector, getMultiPromptUrls, selectHistoryMenuState, messagesSelector, viewEventsSelector, selectViewDataName
  • From @enactor/react-base-components: setKeyboardLayouts, setFormValueStatus

If you need one of these, raise it rather than importing through a deep path into node_modules - deep imports break when the package is rebuilt.

getPages is an action, not a selector

Despite the get prefix, getPages() in the bridge package fetches the current page set from the bridge and dispatches an update. To read pages, use selectPages(state).


Where to look in the source

If you need something not covered here, the source is available under node_modules/@enactor in your project:

WhatPath
Bridge actions@enactor/redux-javascript-bridge/src/actions/
Bridge selectors@enactor/redux-javascript-bridge/src/reducers/
UI actions@enactor/react-base-components/src/actions/
UI selectors@enactor/react-base-components/src/reducers/
Public export listeach package's src/index.js

There is no selectors directory - every selector lives in the reducer file that owns its slice, and each package's src/index.js is the definitive list of what you can import.