Pay attention
This documentation is for the as yet unreleased version of effector Spacewatch 23.0.

useStoreMap

[ ru ]
since

useStoreMap introduced in effector-react 19.1.2

React hook, which subscribes to a store and transforms its value with a given function. The component will update only when the selector function result will change.

You can read the motivation in the issue.

useStoreMap(store, fn)

since

Short version of useStoreMap introduced in effector-react@21.3.0

Common use case: subscribe to changes in selected part of store only

Formulae

useStoreMap<State, Result>(
  store: Store<State>,
  fn: (state: State) => Result
): Result

Arguments

  1. store: Source store
  2. fn ((state) => result): Selector function to receive part of source store

Returns

(Result): Value from the fn function call.

useStoreMap(config)

Overload used when you need to pass dependencies to react (to update items when some of its dependencies are changed)

Formulae

useStoreMap<Source, Result>({
  store: Store<Source>;
  keys: any[];
  fn: (state: Source, keys: any[]) => Result;
  updateFilter?: (newResult: Result, oldResult: Result) => boolean;
  defaultValue?: Result;
}): Result

Arguments

  1. params (Object): Configuration object
    • store: Source store
    • keys (Array): This argument will be passed to React.useMemo to avoid unnecessary updates
    • fn ((state, keys) => result): Selector function to receive part of source store
    • updateFilter ((newResult, oldResult) => boolean): Optional function used to compare old and new updates to prevent unnecessary rerenders. Uses createStore updateFilter option under the hood
    • defaultValue: Optional default value, used whenever fn returns undefined
since

updateFilter option introduced in effector-react@21.3.0

since

defaultValue option introduced in effector-react@22.1.0

Returns

(Result): Value from the fn function call, or the defaultValue.

Example

This hook is useful for working with lists, especially with large ones

import { createStore } from "effector";
import { useStore, useStoreMap } from "effector-react";

const data = [
  {
    id: 1,
    name: "Yung",
  },
  {
    id: 2,
    name: "Lean",
  },
  {
    id: 3,
    name: "Kyoto",
  },
  {
    id: 4,
    name: "Sesh",
  },
];

const $users = createStore(data);
const $ids = createStore(data.map(({ id }) => id));

const User = ({ id }) => {
  const user = useStoreMap({
    store: $users,
    keys: [id],
    fn: (users, [userId]) => users.find(({ id }) => id === userId),
  });

  return (
    <div>
      <strong>[{user.id}]</strong> {user.name}
    </div>
  );
};

const UserList = () => {
  const ids = useStore($ids);

  return ids.map((id) => <User key={id} id={id} />);
};

Try it

Contributors