UNPKG

2.38 kBPlain TextView Raw
1'use strict';
2import { useEffect } from 'react';
3import type { WorkletFunction } from '../commonTypes';
4import { startMapper, stopMapper } from '../core';
5import type { DependencyList } from './commonTypes';
6import { useSharedValue } from './useSharedValue';
7import { shouldBeUseWeb } from '../PlatformChecker';
8
9/**
10 * Lets you to respond to changes in a [shared value](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#shared-value). It's especially useful when comparing values previously stored in the shared value with the current one.
11 *
12 * @param prepare - A function that should return a value to which you'd like to react.
13 * @param react - A function that reacts to changes in the value returned by the `prepare` function.
14 * @param dependencies - an optional array of dependencies. Only relevant when using Reanimated without the Babel plugin on the Web.
15 * @see https://docs.swmansion.com/react-native-reanimated/docs/advanced/useAnimatedReaction
16 */
17// @ts-expect-error This overload is required by our API.
18export function useAnimatedReaction<PreparedResult>(
19 prepare: () => PreparedResult,
20 react: (prepared: PreparedResult, previous: PreparedResult | null) => void,
21 dependencies?: DependencyList
22): void;
23
24export function useAnimatedReaction<PreparedResult>(
25 prepare: WorkletFunction<[], PreparedResult>,
26 react: WorkletFunction<
27 [prepare: PreparedResult, previous: PreparedResult | null],
28 void
29 >,
30 dependencies?: DependencyList
31) {
32 const previous = useSharedValue<PreparedResult | null>(null);
33
34 let inputs = Object.values(prepare.__closure ?? {});
35
36 if (shouldBeUseWeb()) {
37 if (!inputs.length && dependencies?.length) {
38 // let web work without a Reanimated Babel plugin
39 inputs = dependencies;
40 }
41 }
42
43 if (dependencies === undefined) {
44 dependencies = [
45 ...Object.values(prepare.__closure ?? {}),
46 ...Object.values(react.__closure ?? {}),
47 prepare.__workletHash,
48 react.__workletHash,
49 ];
50 } else {
51 dependencies.push(prepare.__workletHash, react.__workletHash);
52 }
53
54 useEffect(() => {
55 const fun = () => {
56 'worklet';
57 const input = prepare();
58 react(input, previous.value);
59 previous.value = input;
60 };
61 const mapperId = startMapper(fun, inputs);
62 return () => {
63 stopMapper(mapperId);
64 };
65 }, dependencies);
66}