Use the Actyx Pond framework fully integrated into React. Expand your toolchain with <Pond>
, useFish
, and usePond
to speed up your UI projects and write distributed apps in a couple of hours.
React-Pond is available as a npm package.
npm install @actyx-contrib/react-pond
You can access the full API documentation and related examples by visiting: https://actyx-contrib.github.io/react-pond
You will find detailed examples here. They can be executed running e.g. `npm run example:chatRoom'.
<Pond>...</Pond>
Wrap your application with the <Pond>
to use you fish everywhere in the code.
ReactDOM.render(
<Pond
manifest={{
appId: 'com.example.react-pond-example',
displayName: 'React Pond Example',
version: '0.0.1'
}}
onError={() => {
setTimeout(() => location.reload(), 5000)
return <div>Connection to Actyx rejected: {JSON.stringify(e)}. Next reconnect in 5 seconds.</div>
}}
>
<AmazingDistributedApp />
</Pond>,
document.getElementById('root')!,
)
useFish
and useFishFn
Write your distributed logic with the well-known fish and get the state as easy as possible.
useFish(fish)
: Hydrate one explicit fish without a factoryuseFishFn(fishFactory, properties)
: Use a factory function to hydrate fish with propertiesconst MaterialRequest = ({ id }: Props) => {
const allOpenMatReq = useFish(MatRequest.allOpen)
const matReq = useFishFn(MatRequest.of, id)
return (
<div>
<div>Open Material Requests: {allOpenMatReq.ids.length}</div>
<div>
Material Request ({id}): {matReq.state.status}
</div>
<button
onClick={() =>
matReq.run((_state, enqueue) => enqueue(Tag('material').withId(id), EventType.Done))
}
>
Done
</button>
</div>
)
}
useRegistryFish
Map your registry fish to the entities and create tables, lists, complex autocomplete fields, ...
const MaterialRequests = () => {
const allOpenMatReq = useRegistryFish(MatRequest.allOpen, reg => reg.ids, MatRequestFish.of)
const done = (matReq: ReactFish<State, Events, string>) => {
matReq.run((_state, enqueue) => enqueue(Tag('material').withId(matReq.props), EventType.Done))
}
return (
<div>
<div>Open Material Requests: {allOpenMatReq.length}</div>
{allOpenMatReq.map(matReq => (
<div key={matReq.props}>
<div>
{matReq.props}: {matReq.state.status}
</div>
<button onClick={() => done(matReq)}>Done</button>
</div>
))}
</div>
)
}
usePond
The pond is not hidden from you. Use it as usual with const pond = usePond()
.
export const App = () => {
const pond = usePond()
const { info, getPondState } = pond
const [pondState, setPondState] = React.useState<PondState>()
React.useEffect(() => {
getPondState(setPondState)
}, [])
return (
<div>
<hr />
<h3>Pond State</h3>
<pre>{JSON.stringify(pondState, undefined, 2)}</pre>
<hr />
<h3>Pond Info</h3>
<pre>{JSON.stringify(info(), undefined, 2)}</pre>
</div>
)
}
React application. Components are shown when the initialize is done
Optionally change the Actyx endpoint the Pond connects to
and provide an error handler if the connection to Actyx is dropped.
Defaults to {}
Component to show during the connect (very shortly)
Manifest describing an Actyx application. Used for authorizing API access.
Use com.example.<somestring>
as appId
for testing and development purposes,
so you don't require a signed certificate.
Example:
{
appId: 'com.example.react-pond-example',
displayName: 'React Pond Example',
version: '0.0.1'
}
Error callback the the pond is not able to reach actyxOS locally
Advanced Pond configuration options.
Defaults to {}
ReactFish type.
This fish will handle all interactions with the React component.
props of the fish
run function for the observed fish
current public state of the observed fish
Top level component to initialize the pond
ReactDOM.render(
<Pond
onError={onError}
manifest={{
appId: 'io.actyx.react-pond-example',
displayName: 'React Pond Example',
version: '0.0.1',
signature: 'v2tz...JBPT3/'
}}
>
<App />
</Pond>,
document.getElementById('root')
)
ReactDOM.render(
<Pond
onError={onError}
manifest={{
appId: 'io.actyx.react-pond-example',
displayName: 'React Pond Example',
version: '0.0.1',
signature: 'v2tz...JBPT3/'
}}
connectionOpts={{
actyxHost: 'actyx',
actyxPort: 4232,
onConnectionLost: onConnectionLostHandler
}}
opts={{
fishErrorReporter: fishErrorReporter
}}
>
<App />
</Pond>,
document.getElementById('root')
)
reactProperties for the pond @see PondProps
React component
Stateful integration of an actyx Pond Fish.
Learn more about the fish: https://developer.actyx.com/docs/pond/getting-started
export const App = () => {
const chatRoomsFish = useFish(ChatRoomFish.channelList)
return (
<div>
<div>List of existing chat rooms</div>
<ul>
{chatRoomsFish.map((name) => <li key={name}>{name}</li>)}
</ul>
</div>
)
}
fish to get the public state for
ReactFish
Stateful integration of an actyx Pond Fish factory.
Learn more about the fish: https://developer.actyx.com/docs/pond/getting-started
export const App = () => {
const [channel, setChannel] = React.useState('lobby')
const chatRoomFish = useFishFn(ChatRoomFish.forChannel, channel)
const send = () =>
chatRoomFish && chatRoomFish.run((_state, enqueue) =>
enqueue(ChatRoom.tags.channel.withId(channel), {
type: 'message',
message,
sender: userName,
channel
})
)
return (
<div>
{chatRoomFish && (
<>
<div>current chat room: {chatRoomFish.props}</div>
<div>
{chatRoomFish.state.map((message, idx) => (
<div key={idx}>{message}</div>
))}
</div>
<div>
<button onClick={send}>send</button>
</div>
</>
)}
</div>
)
}
props for the factory
ReactFish | undefined If the props are undefined
Get the pond in your react application.
Learn more about the pond: https://developer.actyx.com/docs/pond/getting-started
emit<E>(tags: Tags<E>, event: E): PendingEmission;
observe<S, E>(fish: Fish<S, E>, callback: (newState: S) => void): CancelSubscription;
run<S, EWrite>(fish: Fish<S, any>, fn: StateEffect<S, EWrite>): PendingEmission;
keepRunning<S, EWrite>(fish: Fish<S, any>, fn: StateEffect<S, EWrite>, autoCancel?: (state: S) => boolean): CancelSubscription;
dispose(): void;
info(): PondInfo;
getPondState(callback: (newState: PondState) => void): CancelSubscription;
getNodeConnectivity(params: GetNodeConnectivityParams): CancelSubscription;
waitForSwarmSync(params: WaitForSwarmSyncParams): void;
pond instance
Stateful integration of an actyx Pond Fish factory.
Learn more about the fish: https://developer.actyx.com/docs/pond/getting-started
export const App = () => {
const allChatRooms = useRegistryFish(ChatRoom.channelList, (s) => s, ChatRoom.forChannel)
return (
<div>
{allChatRooms.map(f => (
<div key={f.props}>{f.props}: {f.state.join(', ')}</div>
))}
</div>
)
}
fish to get the public state for, or fish factory function
map the registry state to an array of properties used by the mkFish
fish factory function to get the public state for
ReactFish[] entities of the registry
Generated using TypeDoc
Pond component properties to get some feedback