-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Expand file tree
/
Copy pathuseReactiveVar.ts
More file actions
45 lines (42 loc) · 1.46 KB
/
useReactiveVar.ts
File metadata and controls
45 lines (42 loc) · 1.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import * as React from "react";
import type { ReactiveVar } from "@apollo/client";
import { useSyncExternalStore } from "./useSyncExternalStore.js";
/**
* Reads the value of a [reactive variable](https://www.apollographql.com/docs/react/local-state/reactive-variables/) and re-renders the containing component whenever that variable's value changes. This enables a reactive variable to trigger changes _without_ relying on the `useQuery` hook.
*
* @example
*
* ```jsx
* import { makeVar } from "@apollo/client";
* import { useReactiveVar } from "@apollo/client/react";
* export const cartItemsVar = makeVar([]);
*
* export function Cart() {
* const cartItems = useReactiveVar(cartItemsVar);
* // ...
* }
* ```
*
* @param rv - A reactive variable.
* @returns The current value of the reactive variable.
*/
export function useReactiveVar<T>(rv: ReactiveVar<T>): T {
return useSyncExternalStore(
React.useCallback(
(update) => {
// By reusing the same onNext function in the nested call to
// rv.onNextChange(onNext), we can keep using the initial clean-up function
// returned by rv.onNextChange(function onNext(v){...}), without having to
// register the new clean-up function (returned by the nested
// rv.onNextChange(onNext)) with yet another callback.
return rv.onNextChange(function onNext() {
update();
rv.onNextChange(onNext);
});
},
[rv]
),
rv,
rv
);
}