Methods
import { useStoreMap } from "effector-vue/composition";
since

useStoreMap introduced in effector-vue 22.2.0

Function, which subscribes to a store and transforms its value with a given selector. fn receives the state object of the store itself, not a copy or a proxy, and must not mutate it. The returned ComputedRef updates only when the result of the selector changes, so a component reading one item of a large store is not touched by the updates of the other items.

Methods

useStoreMap($store, fn)

since

Short version of useStoreMap introduced in effector-vue 23.3.0

Formulae

useStoreMap(
$store: Store<State>,
fn: (state: State) => Result,
opts?: {scope?: Scope, forceScope?: boolean},
): ComputedRef<Result>;

Arguments

  1. $store: Source Store<State>
  2. fn ((state) => result): Selector function to receive part of source store
  3. opts (Object): Optional scope options

Returns

(ComputedRef<Result>)

Examples

<script setup lang="ts">
import { useStoreMap } from "effector-vue/composition";
import { $user } from "./model";
const name = useStoreMap($user, (user) => user.name);
</script>
<template>
<p>{{ name }}</p>
</template>

useStoreMap(config)

Formulae

useStoreMap({
store: Store<State>,
keys?: MaybeRefOrGetter<Keys>,
fn: (state: State, keys: Keys) => Result,
updateFilter?: (update: Result, current: Result) => boolean,
defaultValue?: Result,
scope?: Scope,
forceScope?: boolean,
}): ComputedRef<Result>;

Arguments

  1. params (Object): Configuration object
    • store: Source store
    • keys (MaybeRefOrGetter<Keys>): Passed to fn as its second argument. A getter or a ref is tracked, so the selector runs again when it changes. A plain value is used as it is
    • fn ((state: State, keys: Keys) => Result): Selector function to receive part of source store
    • updateFilter ((update: Result, current: Result) => boolean): Decides whether a new result of fn replaces the current one. Defaults to update !== current
    • defaultValue (Result): Used every time fn returns undefined
    • scope (Scope) and forceScope (boolean): Scope options of the call
since

scope and forceScope options introduced in effector-vue 23.3.0

since

keys accepts a value or a ref since effector-vue 23.3.0. Before that it accepted a getter only

Returns

(ComputedRef<Result>)

since

Changed in effector-vue 23.3.0:

  • fn receives the state object of the store. Before that it received a proxy, and the state of the store was mutated in place
  • a store that holds null is supported, and a key removed from the state is dropped instead of keeping its last value
  • the subscription is disposed with the effect scope and skipped during a server render

Examples

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

User.vue
<script setup lang="ts">
import { useStoreMap } from "effector-vue/composition";
import { $users } from "./model";
const props = defineProps<{ id: number }>();
const name = useStoreMap({
store: $users,
keys: () => props.id,
fn: (users, userId) => users.find(({ id }) => id === userId)?.name,
defaultValue: "unknown",
});
</script>
<template>
<div>
<strong>[{{ id }}]</strong> {{ name }}
</div>
</template>
App.vue
<script setup lang="ts">
import { useUnit } from "effector-vue/composition";
import { $ids } from "./model";
import User from "./User.vue";
const ids = useUnit($ids);
</script>
<template>
<div>
<User v-for="id in ids" :key="id" :id="id" />
</div>
</template>
model.ts
import { createStore } from "effector";
type User = { id: number; name: string };
export const $users = createStore<User[]>([
{ id: 1, name: "Yung" },
{ id: 2, name: "Lean" },
{ id: 3, name: "Kyoto" },
{ id: 4, name: "Sesh" },
]);
export const $ids = createStore([1, 2, 3, 4]);
export const $count = createStore(0);

Filtering updates

Changed in 23.3.0

Since effector-vue 23.3.0 updateFilter receives the results of fn, as in effector-react. Before that it received the state of the store, so a filter written against the raw state has to be rewritten.

updateFilter receives the results of fn, not the state of the store. A rejected result is dropped, and the previous one stays until an accepted one arrives. A recompute caused by keys goes through the filter as well.

const evenCount = useStoreMap({
store: $count,
fn: (count) => count,
updateFilter: (update) => update % 2 === 0,
});

During a server render there is nothing to filter: the value follows the store until the render ends, and updateFilter is not called.

Contributors