Skip to content
This repository has been archived by the owner on Nov 21, 2022. It is now read-only.

actyx-contrib/react-pond

Repository files navigation

IMPORTANT NOTICE

This repository has been archived and is no longer maintained. You are welcome to copy the code into your own projects and continue using it at your own discretion and risk.

React-Pond

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.

πŸ“¦ Installation

React-Pond is available as a npm package.

npm install @actyx-contrib/react-pond

πŸ“– Documentation and detailed examples

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'.

πŸ€“ Quick start

🌊 <Pond>...</Pond>

Wrap your application with the <Pond> to use you fish everywhere in the code.

Example

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 factory
  • useFishFn(fishFactory, properties): Use a factory function to hydrate fish with properties

πŸ“– Example

const 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, ...

πŸ“– Example

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().

πŸ“– Example

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>
  )
}