Skip to main content

Quick start (code)

Minimal example: a counter with a Ploc and a UseCase-style update.

1. Domain (optional for a counter)

For a simple counter you can skip domain. For real apps, define entities and I*Repository in caf/domain/.

2. Application: Ploc

// caf/application/Counter/Ploc/CounterPloc.ts
import { Ploc } from '@c-a-f/core';

export interface CounterState {
count: number;
}

export class CounterPloc extends Ploc<CounterState> {
constructor() {
super({ count: 0 });
}

increment() {
this.changeState({ ...this.state, count: this.state.count + 1 });
}

decrement() {
this.changeState({ ...this.state, count: this.state.count - 1 });
}
}

3. Setup and provide (React)

// caf/setup.ts
import { CounterPloc } from './application/Counter/Ploc/CounterPloc';

export function setupCounterPloc() {
return new CounterPloc();
}

// App.tsx
import { CAFProvider } from '@c-a-f/infrastructure-react';
import { usePlocFromContext, usePloc } from '@c-a-f/infrastructure-react';
import { setupCounterPloc } from './caf/setup';

const counterPloc = setupCounterPloc();

function Counter() {
const ploc = usePlocFromContext('counter');
if (!ploc) return null;
const [state] = usePloc(ploc);
return (
<div>
<span>{state.count}</span>
<button onClick={() => ploc.increment()}>+</button>
<button onClick={() => ploc.decrement()}>-</button>
</div>
);
}

export default function App() {
return (
<CAFProvider plocs={{ counter: counterPloc }}>
<Counter />
</CAFProvider>
);
}

4. With a UseCase (async)

When you need async work (e.g. API), define a UseCase that returns RequestResult<T> and call it from the Ploc or from the component via useUseCase. See Best practices and the main repo packages/core README.