Skip to content

Commit

Permalink
Add console.warn when there are duplicate refs
Browse files Browse the repository at this point in the history
  • Loading branch information
kristerkari committed Aug 25, 2021
1 parent e3330d3 commit e0c4401
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 37 deletions.
4 changes: 4 additions & 0 deletions example/src/build/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ var ScrollSyncNode = forwardRef(function (props, forwardedRef) {
var children = props.children, _a = props.group, group = _a === void 0 ? "default" : _a, _b = props.scroll, scroll = _b === void 0 ? "two-way" : _b, _c = props.selfLockAxis, selfLockAxis = _c === void 0 ? null : _c, _d = props.onScroll, onNodeScroll = _d === void 0 ? function () { return undefined; } : _d;
var _e = useContext(ScrollingSyncerContext), registerNode = _e.registerNode, unregisterNode = _e.unregisterNode, onScroll = _e.onScroll;
var childRef = children.ref;
var hasDoubleRef = childRef != null && forwardedRef != null;
if (hasDoubleRef) {
console.warn("scroll-sync-react:\nWARNING: ref used on both ScrollSyncNode and its direct child.\nUsing the ref from the ScrollSyncNode component.");
}
var ref = childRef && !forwardedRef ? childRef : useRef(null);
useEffect(function () {
if (typeof forwardedRef === "function") {
Expand Down
8 changes: 8 additions & 0 deletions src/components/ScrollSync/ScrollSyncNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ const ScrollSyncNode: React.ForwardRefExoticComponent<ScrollSyncNodeProps &
const { registerNode, unregisterNode, onScroll } = useContext(ScrollingSyncerContext);

const childRef = (children as any).ref;
const hasDoubleRef = childRef != null && forwardedRef != null;

if (hasDoubleRef) {
console.warn(
"scroll-sync-react:\nWARNING: ref used on both ScrollSyncNode and its direct child.\nUsing the ref from the ScrollSyncNode component.",
);
}

const ref = childRef && !forwardedRef ? childRef : useRef<EventTarget & HTMLElement>(null);

useEffect(() => {
Expand Down
90 changes: 53 additions & 37 deletions tests/ScrollSyncNode.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,61 @@ import { mount } from "enzyme";
import { ScrollSync, ScrollSyncNode } from "../src";

describe("ScrollSyncNode", () => {
it("should support using ref on ScrollSyncNode", () => {
const ref = jest.fn();
mount(
<ScrollSync>
<ScrollSyncNode ref={ref}>
<div />
</ScrollSyncNode>
</ScrollSync>,
);
expect(ref).toHaveBeenCalledTimes(1);
expect(ref.mock.calls[0][0].toString()).toEqual("[object HTMLDivElement]");
});
describe("ref support", () => {
beforeEach(() => {
spyOn(console, "warn");
});

it("should support using ref on the direct child node", () => {
const ref = jest.fn();
mount(
<ScrollSync>
<ScrollSyncNode>
<div ref={ref} />
</ScrollSyncNode>
</ScrollSync>,
);
expect(ref).toHaveBeenCalledTimes(1);
expect(ref.mock.calls[0][0].toString()).toEqual("[object HTMLDivElement]");
});
afterEach(() => {
jest.clearAllMocks();
});

it("should only call ref on ScrollSyncNode when having duplicate refs", () => {
const ref1 = jest.fn();
const ref2 = jest.fn();
mount(
<ScrollSync>
<ScrollSyncNode ref={ref1}>
<div ref={ref2} />
</ScrollSyncNode>
</ScrollSync>,
);
expect(ref1).toHaveBeenCalledTimes(1);
expect(ref1.mock.calls[0][0].toString()).toEqual("[object HTMLDivElement]");
expect(ref2).toHaveBeenCalledTimes(0);
it("should support using ref on ScrollSyncNode", () => {
const ref = jest.fn();
mount(
<ScrollSync>
<ScrollSyncNode ref={ref}>
<div />
</ScrollSyncNode>
</ScrollSync>,
);
expect(ref).toHaveBeenCalledTimes(1);
expect(ref.mock.calls[0][0].toString()).toEqual("[object HTMLDivElement]");
expect(console.warn).toHaveBeenCalledTimes(0);
});

it("should support using ref on the direct child node", () => {
const ref = jest.fn();
mount(
<ScrollSync>
<ScrollSyncNode>
<div ref={ref} />
</ScrollSyncNode>
</ScrollSync>,
);
expect(ref).toHaveBeenCalledTimes(1);
expect(ref.mock.calls[0][0].toString()).toEqual("[object HTMLDivElement]");
expect(console.warn).toHaveBeenCalledTimes(0);
});

it("should only call ref on ScrollSyncNode when having duplicate refs", () => {
const ref1 = jest.fn();
const ref2 = jest.fn();
mount(
<ScrollSync>
<ScrollSyncNode ref={ref1}>
<div ref={ref2} />
</ScrollSyncNode>
</ScrollSync>,
);
expect(ref1).toHaveBeenCalledTimes(1);
expect(ref1.mock.calls[0][0].toString()).toEqual("[object HTMLDivElement]");
expect(ref2).toHaveBeenCalledTimes(0);
expect(console.warn).toHaveBeenCalledTimes(1);
expect(console.warn).toHaveBeenCalledWith(
"scroll-sync-react:\nWARNING: ref used on both ScrollSyncNode and its direct child.\nUsing the ref from the ScrollSyncNode component.",
);
});
});

it("should support using onScroll on ScrollSyncNode", () => {
Expand Down

0 comments on commit e0c4401

Please sign in to comment.