Skip to content

Commit 922cccf

Browse files
committed
[FIX] useMergedRef useIntersectionObserver useResizeObserver hooks
1 parent 889a8d9 commit 922cccf

6 files changed

Lines changed: 48 additions & 35 deletions

File tree

apps/react-tools-demo/src/components/hooks/useMergedRef/UseMergedRef.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useRef, useState } from "react";
1+
import { useCallback, useRef, useState } from "react";
22
import { useMergedRef, useResizeObserver } from "../../../../../../packages/react-tools/src";
33

44
/**
@@ -7,16 +7,15 @@ The component has a ref to change border color of a div element when a button is
77
export const UseMergedRef = () => {
88
const [state, setState] = useState(false);
99
const [refCb] = useResizeObserver<HTMLDivElement>(
10-
(entries: ResizeObserverEntry[]) => {
10+
useCallback((entries: ResizeObserverEntry[]) => {
1111
const result = entries[0].contentRect.width < 100;
1212
result !== state && setState(result);
13-
}
13+
}, [state])
1414
);
1515
const ref = useRef<HTMLDivElement>(null);
1616
const mergedRef = useMergedRef<HTMLDivElement>(ref, refCb);
1717

1818
const changeBorderColor = () => {
19-
mergedRef.current;
2019
ref.current && (ref.current.style.border = ref.current.style.border.indexOf("lightgray") !== -1
2120
? '1px solid darkcyan'
2221
: '1px solid lightgray'

apps/react-tools-demo/src/markdown/useMergedRef.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const UseMergedRef = () => {
1616
const mergedRef = useMergedRef<HTMLDivElement>(ref, refCb);
1717

1818
const changeBorderColor = () => {
19+
mergedRef.current;
1920
ref.current && (ref.current.style.border = ref.current.style.border.indexOf("lightgray") !== -1
2021
? '1px solid darkcyan'
2122
: '1px solid lightgray'

packages/react-tools/src/hooks/useEffectOnce.ts

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,35 +24,32 @@ export const useEffectOnce = (effect: EffectCallback) => {
2424
}, [])
2525
}
2626

27-
/**
28-
*
29-
* INFO this implementation works but gives a rerender.
27+
// INFO this implementation works but gives a rerender.
28+
//
29+
//
30+
// export const useEffectOnce = (effect: EffectCallback) => {
31+
// const update = useRerender();
32+
// const effectFn = useRef(effect);
33+
// const cleanUpFn = useRef<ReturnType<EffectCallback>>();
34+
// const effectCalled = useRef(false);
35+
// const rendered = useRef(false);
3036

31-
export const useEffectOnce = (effect: EffectCallback) => {
32-
const update = useRerender();
33-
const effectFn = useRef(effect);
34-
const cleanUpFn = useRef<ReturnType<EffectCallback>>();
35-
const effectCalled = useRef(false);
36-
const rendered = useRef(false);
37-
38-
if (effectCalled.current) {
39-
rendered.current = true;
40-
}
41-
42-
useEffect(() => {
43-
if (!effectCalled.current) {
44-
cleanUpFn.current = effectFn.current();
45-
effectCalled.current = true
46-
update();
47-
}
48-
return () => {
49-
if (rendered.current) {
50-
cleanUpFn.current && cleanUpFn.current();
51-
effectCalled.current = false
52-
}
53-
}
54-
// eslint-disable-next-line react-hooks/exhaustive-deps
55-
}, []);
56-
}
37+
// if (effectCalled.current) {
38+
// rendered.current = true;
39+
// }
5740

58-
*/
41+
// useEffect(() => {
42+
// if (!effectCalled.current) {
43+
// cleanUpFn.current = effectFn.current();
44+
// effectCalled.current = true
45+
// update();
46+
// }
47+
// return () => {
48+
// if (rendered.current) {
49+
// cleanUpFn.current && cleanUpFn.current();
50+
// effectCalled.current = false
51+
// }
52+
// }
53+
// // eslint-disable-next-line react-hooks/exhaustive-deps
54+
// }, []);
55+
// }

packages/react-tools/src/hooks/useIntersectionObserver.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const useIntersectionObserver = <T extends Element>(cb: IntersectionObser
1111
const observer = useRef<IntersectionObserver>();
1212
const working = useRef(true);
1313
const nodeRef = useRef<T>();
14+
const cbRef = useRef(cb);
1415

1516
useEffectOnce(() => () => {
1617
nodeRef.current = undefined;
@@ -28,6 +29,13 @@ export const useIntersectionObserver = <T extends Element>(cb: IntersectionObser
2829
observer.current = new IntersectionObserver(cb, opts);
2930
observer.current.observe(node);
3031
}
32+
if (cbRef.current !== cb && observer.current && node) {
33+
cbRef.current = cb;
34+
observer.current?.disconnect();
35+
observer.current = undefined;
36+
observer.current = new IntersectionObserver(cb, opts);
37+
observer.current.observe(node);
38+
}
3139
}, [cb, opts]),
3240
useCallback(() => {
3341
if (working.current) {

packages/react-tools/src/hooks/useMergedRef.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ export const useMergedRef = <T>(...refs: React.Ref<T>[]) => {
99
const mergedRef = useRef<T>(null);
1010
useEffect(() => {
1111
refs.forEach(ref => typeof ref === "function" ? ref(mergedRef.current) : (ref as MutableRefObject<T | null>).current = mergedRef.current);
12-
}, [mergedRef.current]);
12+
}, [refs]);
1313
return mergedRef;
1414
}

packages/react-tools/src/hooks/useResizeObserver.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const useResizeObserver = <T extends Element>(cb: ResizeObserverCallback,
1111
const observer = useRef<ResizeObserver>();
1212
const working = useRef(true);
1313
const nodeRef = useRef<T>();
14+
const cbRef = useRef(cb);
1415

1516
useEffectOnce(() => () => {
1617
nodeRef.current = undefined;
@@ -28,6 +29,13 @@ export const useResizeObserver = <T extends Element>(cb: ResizeObserverCallback,
2829
observer.current = new ResizeObserver(cb);
2930
observer.current.observe(node, opts);
3031
}
32+
if (cbRef.current !== cb && observer.current && node) {
33+
cbRef.current = cb;
34+
observer.current?.disconnect();
35+
observer.current = undefined;
36+
observer.current = new ResizeObserver(cb);
37+
observer.current.observe(node, opts);
38+
}
3139
}, [cb, opts]),
3240
useCallback(() => {
3341
if (working.current) {

0 commit comments

Comments
 (0)