Skip to main content
Version: v2.x.x

Basic example

The classic example of a counter

What You'll Learn
  • How to create a simple service and bind it to your React app
Prerequisites

The service

Create the new service

First we create the file counter.service.ts

The created service must extend Service which has been auto-generated in the setup step

export class CounterService extends Service {

}

Service state

Each service has a local state that is automatically proxified with valtio for reactivity

Pass the State type to the extended Service as Service<State>

type State = { count: number };

export class CounterService extends Service<State> {
state: State = { count: 0 };
}

Append a method

Each method has access to the local state which is automatically reactive thanks to valtio

You can directly modify the state properties - valtio will automatically track changes

type State = { count: number };

export class CounterService extends Service<State> {
state: State = { count: 0 };

increment() {
this.state.count++;
}
}

Register the service

In the file _services

import { CounterService } from './counter.service';

export const services = {
counter: CounterService,
};

Wrap the App with the CortexProvider

 <CortexProvider core={createCore()}>
<App />
</CortexProvider>

Use the methods in the app

Use the hook useService with the name of the service, here counter

You can access any method by destructuring this hook return value, and use it in the JSX

const InnerApp: FC = () => {
const { increment } = useService('counter');

return (
<div>
<button onClick={increment}>increment counter value</button>
</div>
);
};

Access the state in the app

You can access the state directly from the service using the typed useService hook. The state is automatically reactive thanks to valtio, so any state change will trigger a re-render.

const InnerApp: FC = () => {
const { increment, count } = useService('counter');

return (
<div>
<button onClick={increment}>+</button>
<span>{count}</span>
</div>
);
};

Test the behavior

Since all the logic is completely decoupled from React, we can test the behavior of our app with Jest

describe('counter', () => {
it('should be incremented', () => {
const core = createCore()

expect(core.getService('counter').state.count).toBe(0)

core.getService('counter').increment()
expect(core.getService('counter').state.count).toBe(1)
})
})