diff --git a/src/fn-wire/use-fn.test.ts b/src/fn-wire/use-fn.test.ts index c4e1aaf..4fe9ca7 100644 --- a/src/fn-wire/use-fn.test.ts +++ b/src/fn-wire/use-fn.test.ts @@ -83,4 +83,82 @@ describe('useFn', () => { }); expect(fn).toBeCalledWith(3); }); + describe('when wire changed', () => { + it('should subscribe to the new wire', () => { + const fn = jest.fn(); + const { result, rerender } = renderHook( + ({ firstWire }: { firstWire: boolean }) => { + const wire1 = useFnsWire<{ test(n: number): void }>(null); + const wire2 = useFnsWire<{ test(n: number): void }>(null); + useFn(firstWire ? wire1 : wire2, 'test', fn); + return { wire1, wire2 }; + }, + { initialProps: { firstWire: true } }, + ); + rerender({ firstWire: false }); + + act(() => { + result.current.wire2.fns.test(3); + }); + expect(fn).toBeCalledWith(3); + }); + it('should unsubscribe from first wire ', () => { + const fn = jest.fn(); + const { result, rerender } = renderHook( + ({ firstWire }: { firstWire: boolean }) => { + const wire1 = useFnsWire<{ test(n: number): void }>(null); + const wire2 = useFnsWire<{ test(n: number): void }>(null); + useFn(firstWire ? wire1 : wire2, 'test', fn); + return { wire1, wire2 }; + }, + { initialProps: { firstWire: true } }, + ); + rerender({ firstWire: false }); + + act(() => { + result.current.wire1.fns.test(3); + }); + expect(fn).not.toBeCalled(); + }); + }); + describe('when up-link wire changed', () => { + it('should subscribe to the new wire', () => { + const fn = jest.fn(); + const { result, rerender } = renderHook( + ({ firstWire }: { firstWire: boolean }) => { + const wire1 = useFnsWire<{ test(n: number): void }>(null); + const wire2 = useFnsWire<{ test(n: number): void }>(null); + const wire = useFnsWire(firstWire ? wire1 : wire2); + useFn(wire, 'test', fn); + return { wire1, wire2 }; + }, + { initialProps: { firstWire: true } }, + ); + rerender({ firstWire: false }); + + act(() => { + result.current.wire2.fns.test(3); + }); + expect(fn).toBeCalledWith(3); + }); + it('should unsubscribe from first wire ', () => { + const fn = jest.fn(); + const { result, rerender } = renderHook( + ({ firstWire }: { firstWire: boolean }) => { + const wire1 = useFnsWire<{ test(n: number): void }>(null); + const wire2 = useFnsWire<{ test(n: number): void }>(null); + const wire = useFnsWire(firstWire ? wire1 : wire2); + useFn(wire, 'test', fn); + return { wire1, wire2 }; + }, + { initialProps: { firstWire: true } }, + ); + rerender({ firstWire: false }); + + act(() => { + result.current.wire1.fns.test(3); + }); + expect(fn).not.toBeCalled(); + }); + }); }); diff --git a/src/fn-wire/use-fn.ts b/src/fn-wire/use-fn.ts index b2eaca9..dbc621b 100644 --- a/src/fn-wire/use-fn.ts +++ b/src/fn-wire/use-fn.ts @@ -1,6 +1,5 @@ import { useEffect } from 'react'; import { KeyOfMethods } from '../utils/type-utils'; -import { useStabilityGuard } from '../utils/use-stability-guard'; import { FnsWire } from './fns-wire'; /** @@ -31,7 +30,6 @@ export function useFn>( name: K, fn: Fns[K], ) { - useStabilityGuard(wire); useEffect(() => { return wire?.fn(name, fn); }, [wire, name, fn]); diff --git a/src/fn-wire/use-fns-wire.ts b/src/fn-wire/use-fns-wire.ts index 522a70b..7e5725b 100644 --- a/src/fn-wire/use-fns-wire.ts +++ b/src/fn-wire/use-fns-wire.ts @@ -1,11 +1,20 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { createFnsWire } from './create-fns-wire'; import { FnsWire } from './fns-wire'; +const create = (upLink: FnsWire | null | undefined) => { + return createFnsWire(upLink || {}); +}; + export function useFnsWire( upLink: FnsWire | null | undefined, ): FnsWire { - const [[wire, connect]] = useState(() => createFnsWire(upLink || {})); + const [[wire, connect], set] = useState(() => create(upLink)); + const lastUpLinkRef = useRef(upLink); + if (lastUpLinkRef.current !== upLink) { + lastUpLinkRef.current = upLink; + set(create(upLink)); + } useEffect(() => { return connect(); }, [connect]);