@effector/contract
Usage
import { contract } from '@effector/contract';
Create a model in a model.ts
file and export all effector units:
import { createEvent, createStore } from 'effector';
export const buttonClicked = createEvent();
export const $counter = createStore(0);
$counter.on(buttonClicked, (counter) => counter + 1);
Create a page component in a page.tsx
:
import React from 'react';
import { Text, Button } from 'my-ui';
export const ExamplePage = () => (
<div>
<Text>Counter: 1</Text>
<Button onClick={() => {
}}>Increment</Button>
</div>
);
Now create effector units to correctly connects with:
import React from 'react';
import { createEvent, createStore } from 'effector';
import { useStore, useEvent } from 'effector-react';
import { Text, Button } from 'my-ui';
export const buttonClicked = createEvent();
export const $counter = createStore(0);
export const ExamplePage = () => (
<div>
<CounterText />
<Increment />
</div>
);
const CounterText = () => {
const counter = useStore($counter);
return <Text>Counter: {counter}</Text>;
};
const Increment = () => {
const handler = useEvent(buttonClicked);
return <Button onClick={handler}>Increment</Button>;
};
Also, you can use @effector/reflect
:
import React from 'react';
import { createEvent, createStore } from 'effector';
import { reflect } from '@effector/reflect';
import { Text, Button } from 'my-ui';
export const buttonClicked = createEvent();
export const $counter = createStore(0);
export const ExamplePage = () => (
<div>
<CounterText />
<Increment />
</div>
);
const CounterText = reflect({
view: Text,
bind: { children: $counter.map((counter) => `Counter: ${counter}`) },
});
const Increment = reflect({
view: Button,
bind: {
onClick: buttonClicked.prepend(() => {
})
},
});
Now you can connect the model with the page, create index.ts
file:
import { contract } from '@effector/contract';
import * as model from './model';
import * as page from './page';
export { ExamplePage } from './page';
contract({ page, model });