factories
In Effector's world any factory is a function that returns a set of Stores, Events or Effects. It's a way to encapsulate some logic and reuse it in different places.
If your application has any unit-tests or meant to be rendered on the server (SSR) factories have to be added to factories
field in config of effector/babel-plugin
or @effector/swc-plugin
. The reasons of this limitation are described in this article.
In real world it is easy to add any third-party library that uses factories to the config because it has an exact import path. But adding factories from your own code is a bit more complicated. There are no automatic ways to validate that all factories are added to the config. This library is solving this problem: just add @withease/factories
to the config and use it to create and invoke factories.
Also, this library covers a few edge-cases that are really important for SSR. To learn more about them, read the motivation.
Installation
First, you need to install package:
pnpm install @withease/factories
yarn add @withease/factories
npm install @withease/factories
Second, you need to add @withease/factories
to the config of effector/babel-plugin
or @effector/swc-plugin
:
{
"plugins": [["effector/babel-plugin"]]
}
{
"$schema": "https://json.schemastore.org/swcrc",
"jsc": {
"experimental": {
"plugins": [["@effector/swc-plugin"]]
}
}
}
That's it! Now you can use @withease/factories
to create and invoke factories across your application.
API
createFactory
To create a factory you need to call createFactory
with a factory creator callback:
import { createStore, createEvent, sample } from 'effector';
import { createFactory } from '@withease/factories';
const createCounter = createFactory(({ initialValue }) => {
const $counter = createStore(initialValue);
const increment = createEvent();
const decrement = createEvent();
sample({
clock: increment,
source: $counter,
fn: (counter) => counter + 1,
target: $counter,
});
sample({
clock: decrement,
source: $counter,
fn: (counter) => counter - 1,
target: $counter,
});
return {
$counter,
increment,
decrement,
};
});
invoke
Anywhere in your application you can invoke a factory by calling invoke
with a factory and its arguments:
import { invoke } from '@withease/factories';
const counter = invoke(createCounter, { initialValue: 2 });
WARNING
You have to invoke factories only in the top-level of your application. It means that you must not invoke it during component rendering or in any other place that can be called multiple times. Otherwise, you will get a memory leak.
This limitation is applied to any factory, not only to factories created with @withease/factories
.