reflect
import { reflect } from '@effector/reflect';
const Component = reflect({
view: SourceComponent,
bind: Props,
hooks: Hooks,
});
Static method to create a component bound to effector stores and events as stores.
Arguments
view
— A react component that should be used to bind tobind
— Object of effector stores, events or any valuehooks
— Optional object{ mounted, unmounted }
to handle when component is mounted or unmounted.useUnitConfig
- Optional configuration object, which is passed directly to the second argument ofuseUnit
fromeffector-react
.
Returns
- A react component with bound values from stores and events.
Example
// ./user.tsx
import { reflect } from '@effector/reflect';
import { createEvent, restore } from 'effector';
import React, { ChangeEvent, FC } from 'react';
// Base components
type InputProps = {
value: string;
onChange: ChangeEvent<HTMLInputElement>;
placeholder?: string;
};
const Input: FC<InputProps> = ({ value, onChange, placeholder }) => {
return <input value={value} onChange={onChange} placeholder={placeholder} />;
};
// Model
const changeName = createEvent<string>();
const $name = restore(changeName, '');
const changeAge = createEvent<number>();
const $age = restore(changeAge, 0);
const inputChanged = (event: ChangeEvent<HTMLInputElement>) => {
return event.currentTarget.value;
};
// Components
const Name = reflect({
view: Input,
bind: {
value: $name,
placeholder: 'Name',
onChange: changeName.prepend(inputChanged),
},
});
const Age = reflect({
view: Input,
bind: {
value: $age,
placeholder: 'Age',
onChange: changeAge.prepend(parseInt).prepend(inputChanged),
},
});
export const User: FC = () => {
return (
<div>
<Name />
<Age />
</div>
);
};
Fork API auto-compatibility
This feature is available since 9.0.0
release of Reflect.
The Fork API (opens in a new tab) - is a feature of Effector, which allows to seamlessly create virtualized instances of the application's state and logic called Scope (opens in a new tab)'s.
In React to render an App in specific Scope
a Provider (opens in a new tab) component should be used.
When an external system (like React) calls an Effector event and Fork API is used - target Scope
should be provided before call via allSettled
or scopeBind
API.
The reflect
operator does it for you under the hood, so you can provide arbitary callbacks into bind
:
const Age = reflect({
view: Input,
bind: {
value: $age,
placeholder: 'Age',
onChange: (event) => {
changeAge(parseInt(event.currentTarget.value));
},
},
});
☝️ This feature works for bind
field in all of Reflect operators.
In most cases your callbacks will be synchronous and you will not need to do anything besides using Provider (opens in a new tab) to set the Scope for the whole React tree.
Special case: Asynchronous callbacks
Asynchronous callbacks are also allowed, but those should follow the rules of Imperative Effect calls with Scope (opens in a new tab) to be compatible.