API
list

list

import { list } from '@effector/reflect';
const Items: React.FC = list({
  view: React.FC<Props>,
  source: Store<Item[]>,
  bind: {
    // regular reflect's bind, for list item view
  },
  hooks: {
    // regular reflect's hooks, for list item view
  },
  mapItem: {
    propName: (item: Item, index: number) => propValue, // maps array store item to View props
  },
  getKey: (item: Item) => React.Key, // optional, will use index by default
});

Method creates component, which renders list of view components based on items in array in source store, each item content's will be mapped to View props by mapItem rules. On changes to source store, rendered list will be updated too

Arguments

  1. source — Store of Item[] value.
  2. view — A react component, will be used to render list items
  3. mapItem — Object { propName: (Item, index) => propValue } that defines rules, by which every Item will be mapped to props of each rendered list item.
  4. bind — Optional object of stores, events, and static values that will be bound as props to every list item.
  5. hooks — Optional object { mounted, unmounted } to handle when any list item component is mounted or unmounted.
  6. getKey - Optional function (item: Item) => React.Key to set key for every item in the list to help React with effecient rerenders. If not provided, index is used. See effector-react (opens in a new tab) docs for more details.
  7. useUnitConfig - Optional configuration object, which is passed directly to the second argument of useUnit from effector-react.

Returns

  • A react component that renders a list of view components based on items of array in source store. Every view component props are bound to array item contents by the rules in mapItem, and to stores and events in bind, like with regular reflect

Example

import { list } from '@effector/reflect';
import { createEvent, createStore } from 'effector';
import React from 'react';
 
const $color = createStore('red');
 
const $users = createStore([
  { id: 1, name: 'Yung' },
  { id: 2, name: 'Lean' },
  { id: 3, name: 'Kyoto' },
  { id: 4, name: 'Sesh' },
]);
 
const Item = ({ id, name, color }) => {
  return (
    <li style={{ color }}>
      {id} - {name}
    </li>
  );
};
 
const Items = list({
  view: Item,
  source: $users,
  bind: {
    color: $color,
  },
  mapItem: {
    id: (user) => user.id,
    name: (user) => user.name,
  },
  getKey: (user) => `${user.id}${user.name}`,
});
 
<List>
  <Items />
</List>;

Fork API auto-compatibility

This feature is available since 9.0.0 release of Reflect.

The list operator also supports automatic Fork API support for callbacks created from mapItem:

const userChanged = createEvent();
const Items = list({
  view: Item,
  source: $users,
  bind: {
    color: $color,
  },
  mapItem: {
    id: (user) => user.id,
    name: (user) => user.name,
    onChange: (user) => (nextUser) => {
      userChanged({ oldUser: user, nextUser });
    },
  },
  getKey: (user) => `${user.id}${user.name}`,
});

☝️ Notice, how mapItem.onChange creates a event handler callback for every rendered item. Those callbacks are also binded to Scope, if it is provided. For more details read the "Fork API auto-compatibility" part of the reflect operator documentation.