diff --git a/lib/reactObserver/RenderFn.ts b/lib/reactObserver/RenderFn.ts index 18d6d93..a8a0264 100644 --- a/lib/reactObserver/RenderFn.ts +++ b/lib/reactObserver/RenderFn.ts @@ -1,5 +1,10 @@ -import { FC } from 'react' +import { FC, ForwardedRef } from 'react' import Observe from './Observe' -type RenderFn

= (observe: Observe, props: P) => ReturnType + +type RenderFn = ( + observe: Observe, + props: Props, + ref: ForwardedRef +) => ReturnType export default RenderFn diff --git a/lib/reactObserver/reactObserver.ts b/lib/reactObserver/reactObserver.ts index 1fc4d98..43205b0 100644 --- a/lib/reactObserver/reactObserver.ts +++ b/lib/reactObserver/reactObserver.ts @@ -1,28 +1,30 @@ import RenderFn from './RenderFn' -import { FC, useRef } from 'react' +import { forwardRef, useRef } from 'react' import Observable from '../Observable' import diff from 'set-diffs' import useRerender from '@utilityjs/use-force-rerender' -const reactObserver =

(renderFn: RenderFn

): FC

=> (props) => { - const rerender = useRerender() - const previousObservablesRef = useRef(new Set>()) - const observables = new Set>() - const returnValue = renderFn((observable) => { - observables.add(observable) - return observable.getValue() - }, props) +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +const reactObserver = (renderFn: RenderFn) => + forwardRef((props, ref) => { + const rerender = useRerender() + const previousObservablesRef = useRef(new Set>()) + const observables = new Set>() + const returnValue = renderFn((observable) => { + observables.add(observable) + return observable.getValue() + }, props, ref) - const { add, remove } = diff(previousObservablesRef.current, observables) - add.forEach(({ addRemove: { add } }) => { - add(rerender) - }) - remove.forEach(({ addRemove: { remove } }) => { - remove(rerender) - }) - previousObservablesRef.current = observables + const { add, remove } = diff(previousObservablesRef.current, observables) + add.forEach(({ addRemove: { add } }) => { + add(rerender) + }) + remove.forEach(({ addRemove: { remove } }) => { + remove(rerender) + }) + previousObservablesRef.current = observables - return returnValue -} + return returnValue + }) export default reactObserver