Skip to content

Commit

Permalink
feat: supportNodeRef
Browse files Browse the repository at this point in the history
  • Loading branch information
MadCcc committed Aug 23, 2023
1 parent c374970 commit c822f65
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 12 deletions.
15 changes: 14 additions & 1 deletion src/ref.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable no-param-reassign */
import type * as React from 'react';
import { isMemo } from 'react-is';
import { isValidElement, ReactNode } from 'react';
import { isFragment, isMemo } from 'react-is';
import useMemo from './hooks/useMemo';

export function fillRef<T>(ref: React.Ref<T>, node: T) {
Expand Down Expand Up @@ -56,4 +57,16 @@ export function supportRef(nodeOrComponent: any): boolean {

return true;
}

export function supportNodeRef(node: ReactNode): boolean {
if (!isValidElement(node)) {
return false;
}

if (isFragment(node)) {
return false;
}

return supportRef(node);
}
/* eslint-enable */
43 changes: 32 additions & 11 deletions tests/ref.test.js → tests/ref.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
/* eslint-disable no-eval */
import { fireEvent, render } from '@testing-library/react';
import React from 'react';
import React, { ReactNode } from 'react';
import useEvent from '../src/hooks/useEvent';
import { composeRef, supportRef, useComposeRef } from '../src/ref';
import {
composeRef,
supportNodeRef,
supportRef,
useComposeRef,
} from '../src/ref';

describe('ref', () => {
describe('composeRef', () => {
Expand All @@ -12,7 +17,7 @@ describe('ref', () => {

const mergedRef = composeRef(refFunc1, refFunc2);
const testRefObj = {};
mergedRef(testRefObj);
(mergedRef as any)(testRefObj);
expect(refFunc1).toHaveBeenCalledWith(testRefObj);
expect(refFunc2).toHaveBeenCalledWith(testRefObj);
});
Expand All @@ -25,7 +30,7 @@ describe('ref', () => {

it('useComposeRef', () => {
const Demo = ({ ref1, ref2 }) => {
const mergedRef = useComposeRef(ref1, ref2);
const mergedRef = useComposeRef<HTMLDivElement>(ref1, ref2);
return <div ref={mergedRef} />;
};

Expand Down Expand Up @@ -70,14 +75,14 @@ describe('ref', () => {
});

describe('supportRef', () => {
class Holder extends React.Component {
class Holder extends React.Component<{ children: ReactNode }> {
render() {
return this.props.children;
}
}

it('function component', () => {
const holderRef = React.createRef();
const holderRef = React.createRef<Holder>();

function FC() {
return <div />;
Expand All @@ -93,7 +98,7 @@ describe('ref', () => {
});

it('arrow function component', () => {
const holderRef = React.createRef();
const holderRef = React.createRef<Holder>();

// Use eval since jest will convert arrow function to function
const FC = eval('() => null');
Expand All @@ -107,7 +112,7 @@ describe('ref', () => {
});

it('forwardRef function component', () => {
const holderRef = React.createRef();
const holderRef = React.createRef<Holder>();

const FRC = React.forwardRef(() => <div />);
render(
Expand All @@ -120,7 +125,7 @@ describe('ref', () => {
});

it('class component', () => {
const holderRef = React.createRef();
const holderRef = React.createRef<Holder>();

class CC extends React.Component {
state = {};
Expand All @@ -139,7 +144,7 @@ describe('ref', () => {
});

it('memo of function component', () => {
const holderRef = React.createRef();
const holderRef = React.createRef<Holder>();

const FC = () => <div />;
const MemoFC = React.memo(FC);
Expand All @@ -153,7 +158,7 @@ describe('ref', () => {
});

it('memo of forwardRef function component', () => {
const holderRef = React.createRef();
const holderRef = React.createRef<Holder>();

const FRC = React.forwardRef(() => <div />);
const MemoFC = React.memo(FRC);
Expand All @@ -166,4 +171,20 @@ describe('ref', () => {
expect(supportRef(holderRef.current.props.children)).toBeTruthy();
});
});

describe('nodeSupportRef', () => {
it('invalid element but valid ReactNode', () => {
expect(supportNodeRef(true)).toBeFalsy();
expect(supportNodeRef('div')).toBeFalsy();
expect(supportNodeRef(123)).toBeFalsy();
expect(supportNodeRef(<></>)).toBeFalsy();
});

it('FC', () => {
const FC = () => <div />;
const RefFC = React.forwardRef(FC);
expect(supportNodeRef(<FC />)).toBeFalsy();
expect(supportNodeRef(<RefFC />)).toBeTruthy();
});
});
});

0 comments on commit c822f65

Please sign in to comment.