API
reflect

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

  1. view — A react component that should be used to bind to
  2. bind — Object of effector stores, events or any value
  3. hooks — Optional object { mounted, unmounted } to handle when component is mounted or unmounted.
  4. useUnitConfig - Optional configuration object, which is passed directly to the second argument of useUnit from effector-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.