Skip to main content

React bindings

Everything on this page is exported from @datalayer/reactor/react. The core runtime does not import React, so a platform can run without it.

ExportWhat it does
useReactorregisters the reactor in the zustand store and manages its lifecycle
ReactorSlotrenders plugin-provided components by named slot
useSlotComponentswhat is currently in a slot — for a layout that must adapt when it empties
useReactorPlatformreactor access for runtime toggles
useContributionssubscribes to a contribution point
ReactorViewHostrenders the one contribution the application chose
ReactorLazya lazily-loaded component with Suspense and an error boundary
usePluginManifeststhe plugin list
useExtensionManifeststhe extensions
useGroupedPluginManifeststhe plugin list arranged by the extension that delivered it
useBackendPluginwhether an optional backend plugin is present
useReactorEventfires an event when a value changes — activating and deactivating whatever was waiting on it

Mounting a platform

const reactor = buildReactorFromPlugins([HeaderPlugin, StoreExtension]);

export default function App() {
useReactor(reactor, { isBackendPluginAvailable });
return <ReactorSlot slot="header" />;
}

isBackendPluginAvailable is the predicate that decides whether a component gated on requiredBackendPlugins renders. Pass it as a hook result, not a bare function, so that the reactor is told when the answer changes.

Slots

<ReactorSlot slot="cart-actions" />

ReactorSlot renders a fragment. A slot filled by two plugins puts two children wherever it sits — which in a CSS grid means two grid items, in two columns. Wrap a slot in a <div> of your own when its contents must stay together:

<Box sx={{ display: 'grid', gap: 4 }}>
<ReactorSlot slot="main" />
</Box>

Asking whether a slot is empty

A layout with a column per slot has to have an answer for the column being switched off:

const hasShop = useSlotComponents('main').length > 0;

With the shop off there is no first column, and what is left takes the whole width rather than sitting beside a hole. The music example does exactly this.

Subscribing to a contribution point

const rules = useContributions(PlaylistRulePoint);

This re-renders on its own when a contributing plugin is enabled or disabled, so a chooser built from it is never stale. Reading the point is also an activation event: plugins waiting on it are fetched by this call.