blob: 6f89312e5289a49490736beaf3b3241fae2067e8 [file] [log] [blame]
simon5c677962022-12-02 16:51:54 -05001/*
2 * Copyright (C) 2022 Savoir-faire Linux Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation; either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
13 *
14 * You should have received a copy of the GNU Affero General Public
15 * License along with this program. If not, see
16 * <https://www.gnu.org/licenses/>.
17 */
18import { useEffect } from 'react';
19
20export type ConditionalHookProps<T, A> = {
21 useHook: (args: A) => T;
22 args: A;
23 callback?: (value: T) => void;
24 unmountCallback?: (prevValue: T) => void;
25};
26
27/**
28 * Component that, when mounted, calls `useHook` and passes its return value as an argument to the `callback` function.
29 *
30 * @example
31 * // Conditionally call `useMyHook` with arguments `myArgs`
32 * <>
33 * {myCondition && (
34 * <HookComponent
35 * useHook={useMyHook}
36 * args={myArgs}
37 * callback={(v) => console.log(v)}
38 * />
39 * )}
40 * </>
41 *
42 */
43const HookComponent = <T, A>({
44 useHook,
45 args,
46 callback = () => {},
47 unmountCallback = () => {},
48}: ConditionalHookProps<T, A>) => {
49 const value = useHook(args);
50
51 useEffect(() => {
52 callback(value);
53
54 return () => {
55 unmountCallback(value);
56 };
57 }, [value, callback, unmountCallback]);
58
59 return null;
60};
61
62export default HookComponent;