Skip to content

Commit 599cace

Browse files
committed
fix: Undefined HTMLElement is no longer an issue in certain SSR edge cases.
Passing in a custom ref would make the hook check for `instanceof HTMLElement`, which fails in SSR environments. (Node, JSDom) Fixes #74 #62
1 parent 9c3f169 commit 599cace

File tree

2 files changed

+12
-20
lines changed

2 files changed

+12
-20
lines changed

src/index.ts

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,8 @@ function useResolvedElement<T extends HTMLElement>(
1919
subscriber: (element: T) => SubscriberResponse,
2020
refOrElement?: T | RefObject<T> | null
2121
): RefCallback<T> {
22-
// The default ref has to be non-conditionally declared here whether or not
23-
// it'll be used as that's how hooks work.
24-
// @see https://reactjs.org/docs/hooks-rules.html#explanation
25-
let ref: RefObject<T> | null = null; // Default ref
26-
const refElement = useRef<T | null>(null);
2722
const callbackRefElement = useRef<T | null>(null);
28-
const refCallback = useCallback((element: T) => {
23+
const refCallback = useCallback<RefCallback<T>>((element) => {
2924
callbackRefElement.current = element;
3025
callSubscriber();
3126
}, []);
@@ -36,10 +31,12 @@ function useResolvedElement<T extends HTMLElement>(
3631
let element = null;
3732
if (callbackRefElement.current) {
3833
element = callbackRefElement.current;
39-
} else if (refElement.current) {
40-
element = refElement.current;
41-
} else if (refOrElement instanceof HTMLElement) {
42-
element = refOrElement;
34+
} else if (refOrElement) {
35+
if (refOrElement instanceof HTMLElement) {
36+
element = refOrElement;
37+
} else {
38+
element = refOrElement.current;
39+
}
4340
}
4441

4542
if (lastReportedElementRef.current === element) {
@@ -59,11 +56,6 @@ function useResolvedElement<T extends HTMLElement>(
5956
}
6057
};
6158

62-
if (refOrElement && !(refOrElement instanceof HTMLElement)) {
63-
// Overriding the default ref with the given one
64-
ref = refOrElement;
65-
}
66-
6759
// On each render, we check whether a ref changed, or if we got a new raw
6860
// element.
6961
useEffect(() => {
@@ -72,11 +64,8 @@ function useResolvedElement<T extends HTMLElement>(
7264
// the current ref value, but there's no guarantee that the ref value will
7365
// not change later without a render.
7466
// This may or may not be a problem depending on the specific use case.
75-
if (ref) {
76-
refElement.current = ref.current;
77-
}
7867
callSubscriber();
79-
}, [ref, ref?.current, refOrElement]);
68+
}, [refOrElement]);
8069

8170
return refCallback;
8271
}

tests/ssr/Test.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ const useResizeObserver =
77
baseUseResizeObserver.default || baseUseResizeObserver;
88

99
module.exports = function Test() {
10-
const { ref, width = 1, height = 2 } = useResizeObserver();
10+
// Pasting in our own ref here, as this used to cause issues with SSR:
11+
// @see https://github.com/ZeeCoder/use-resize-observer/issues/74
12+
const ref = React.useRef(null);
13+
const { width = 1, height = 2 } = useResizeObserver({ ref });
1114

1215
return React.createElement(
1316
"div",

0 commit comments

Comments
 (0)