import { useUnit } from "effector-react";
since

useUnit introduced in effector-react 22.1.0

React hook, which takes any unit or shape of units.

In the case of stores, it subscribes the component to the provided store and returns its current value, so when the store updates, the component will update automatically.

In the case of events/effects – it binds to the current scope to use in DOM event handlers. Only the effector-react/scope version works this way; the useUnit of effector-react is no-op for events and does not require a Provider with scope.

Methods

useUnit(unit)

Creates function that calls original unit but bounded to Scope if provided.

Formulae

useUnit(event: EventCallable<T>): (payload: T) => T;
useUnit(effect: Effect<Params, Done, any>): (payload: Params) => Promise<Done>;

Arguments

  1. unit (EventCallable<T> or Effect<Params, Done, Fail>): Event or effect which will be bound to the current scope.

Returns

(Function): Function to pass to event handlers. Will trigger the given unit in the current scope.

Examples

Basic

import { createEvent, createStore, fork } from "effector";
import { useUnit, Provider } from "effector-react";
import { render } from "react-dom";

const incrementClicked = createEvent();
const $count = createStore(0);

$count.on(incrementClicked, (count) => count + 1);

const App = () => {
  const [count, onIncrement] = useUnit([$count, incrementClicked]);

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => onIncrement()}>increment</button>
    </>
  );
};

const scope = fork();

render(
  () => (
    <Provider value={scope}>
      <App />
    </Provider>
  ),
  document.getElementById("root"),
);

useUnit($store)

Reads value from the $store and rerenders component when $store updates in Scope if provided.

Formulae

useUnit($store: Store<T>): T;

Arguments

  1. $store: effector (Store)

Returns

Current value of the store.

Examples

Basic

import { createStore, createApi } from "effector";
import { useUnit } from "effector-react";

const $counter = createStore(0);

const { incrementClicked, decrementClicked } = createApi($counter, {
  incrementClicked: (count) => count + 1,
  decrementClicked: (count) => count - 1,
});

const App = () => {
  const counter = useUnit($counter);
  const [onIncrement, onDecrement] = useUnit([incrementClicked, decrementClicked]);

  return (
    <div>
      {counter}
      <button onClick={onIncrement}>Increment</button>
      <button onClick={onDecrement}>Decrement</button>
    </div>
  );
};

useUnit(shape)

Formulae

useUnit({ a: Store<A>, b: Event<B>, ... }): { a: A, b: (payload: B) => B; ... }

useUnit([Store<A>, Event<B>, ... ]): [A, (payload: B) => B, ... ]

Arguments

  1. shape: Object or array of (EventCallable, Effect, or Store)

Returns

(Object or Array):

  • If passed EventCallable or Effect: Functions with the same names or keys as the argument to pass to event handlers. Will trigger the given unit in the current scope.
    Note: events or effects will be bound to Scope only if component wrapped into Provider.
  • If passed Store: The current value of the store.

Examples

Basic

import { createStore, createEvent, fork } from "effector";
import { useUnit, Provider } from "effector-react";

const incremented = createEvent();
const decremented = createEvent();

const $count = createStore(0);

$count.on(incremented, (count) => count + 1);
$count.on(decremented, (count) => count - 1);

const App = () => {
  const count = useUnit($count);
  const on = useUnit({ incremented, decremented });
  // or
  const [a, b] = useUnit([incremented, decremented]);

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => on.incremented()}>increment</button>
      <button onClick={() => on.decremented()}>decrement</button>
    </>
  );
};

const scope = fork();

render(
  () => (
    <Provider value={scope}>
      <App />
    </Provider>
  ),
  document.getElementById("root"),
);
Contributors