1- /* eslint-disable react/require-default-props */
2- /* eslint-disable react/forbid-prop-types */
3- import React from 'react' ;
41import { render } from '@testing-library/react' ;
5- import propTypes from 'prop-types ' ;
2+ import React from 'react ' ;
63
74import useForkRef from './useForkRef' ;
85
@@ -18,10 +15,10 @@ afterEach(() => {
1815
1916describe ( 'useForkRef' , ( ) => {
2017 it ( 'returns a single ref-setter function that forks the ref to its inputs' , ( ) => {
21- function Component ( props ) {
18+ function Component ( props : { innerRef : React . RefObject < HTMLDivElement > } ) {
2219 const { innerRef } = props ;
23- const ownRef = React . useRef ( null ) ;
24- const [ , forceUpdate ] = React . useState ( 0 ) ;
20+ const ownRef = React . useRef < HTMLDivElement > ( ) ;
21+ const [ , forceUpdate ] = React . useState ( true ) ;
2522 React . useEffect ( ( ) => forceUpdate ( n => ! n ) , [ ] ) ;
2623
2724 const handleRef = useForkRef ( innerRef , ownRef ) ;
@@ -31,19 +28,18 @@ describe('useForkRef', () => {
3128 ) ;
3229 }
3330
34- Component . propTypes = {
35- innerRef : propTypes . any
36- } ;
37-
38- const outerRef = React . createRef ( ) ;
31+ const outerRef = React . createRef < HTMLDivElement > ( ) ;
3932 render ( < Component innerRef = { outerRef } /> ) ;
4033
41- expect ( outerRef . current . textContent ) . toBe ( 'has a ref' ) ;
34+ expect ( outerRef . current ? .textContent ) . toBe ( 'has a ref' ) ;
4235 expect ( console . error ) . not . toHaveBeenCalled ( ) ;
4336 } ) ;
4437
4538 it ( 'forks if only one of the branches requires a ref' , ( ) => {
46- const Component = React . forwardRef ( function Component ( props , ref ) {
39+ const Component = React . forwardRef < HTMLDivElement > ( function Component (
40+ _ ,
41+ ref
42+ ) {
4743 const [ hasRef , setHasRef ] = React . useState ( false ) ;
4844 const handleOwnRef = React . useCallback ( ( ) => setHasRef ( true ) , [ ] ) ;
4945 const handleRef = useForkRef ( handleOwnRef , ref ) ;
@@ -58,16 +54,26 @@ describe('useForkRef', () => {
5854 } ) ;
5955
6056 it ( 'does nothing if none of the forked branches requires a ref' , ( ) => {
61- const Outer = React . forwardRef ( function Outer ( props , ref ) {
57+ const setRef = jest . fn ( ) ;
58+
59+ type OuterProps = {
60+ children : React . ReactElement ;
61+ } ;
62+
63+ const Outer = React . forwardRef < null , OuterProps > ( function Outer (
64+ props ,
65+ ref
66+ ) {
6267 const { children } = props ;
63- const handleRef = useForkRef ( children . ref , ref ) ;
6468
65- return React . cloneElement ( children , { ref : handleRef } ) ;
66- } ) ;
69+ // TODO: Fix this test as reading ref from children is not allowed so not available on React types
70+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
71+ // @ts -ignore
72+ const handleRef = useForkRef ( children ?. ref , ref ) ;
73+ setRef ( handleRef ) ;
6774
68- // TODO: Figure out how to make react/no-unused-prop-types happy with the children
69- // eslint-disable-next-line react/no-unused-prop-types
70- Outer . propTypes = { children : propTypes . element . isRequired } ;
75+ return children ? React . cloneElement ( children , { ref : handleRef } ) : null ;
76+ } ) ;
7177
7278 function Inner ( ) {
7379 return < div /> ;
@@ -79,55 +85,56 @@ describe('useForkRef', () => {
7985 </ Outer >
8086 ) ;
8187 expect ( console . error ) . not . toHaveBeenCalled ( ) ;
88+ expect ( setRef ) . toHaveBeenCalledWith ( null ) ;
8289 } ) ;
8390
8491 describe ( 'changing refs' , ( ) => {
85- function Div ( props ) {
86- const { leftRef, rightRef, ...other } = props ;
92+ function Div (
93+ props : {
94+ leftRef ?: React . Ref < HTMLDivElement > ;
95+ rightRef ?: React . Ref < HTMLDivElement > ;
96+ } & React . HTMLAttributes < HTMLDivElement >
97+ ) {
98+ const { leftRef = null , rightRef = null , ...other } = props ;
8799 const handleRef = useForkRef ( leftRef , rightRef ) ;
88100
89101 return < div { ...other } ref = { handleRef } /> ;
90102 }
91103
92- Div . propTypes = {
93- leftRef : propTypes . oneOfType ( [ propTypes . func , propTypes . object ] ) ,
94- rightRef : propTypes . oneOfType ( [ propTypes . func , propTypes . object ] )
95- } ;
96-
97104 it ( 'handles changing from no ref to some ref' , ( ) => {
98105 const { rerender } = render ( < Div id = 'test' /> ) ;
99106
100107 expect ( console . error ) . not . toHaveBeenCalled ( ) ;
101108
102- const ref = React . createRef ( ) ;
109+ const ref = React . createRef < HTMLDivElement > ( ) ;
103110 rerender ( < Div id = 'test' leftRef = { ref } /> ) ;
104111
105- expect ( ref . current . id ) . toBe ( 'test' ) ;
112+ expect ( ref . current ? .id ) . toBe ( 'test' ) ;
106113 expect ( console . error ) . not . toHaveBeenCalled ( ) ;
107114 } ) ;
108115
109116 it ( 'cleans up detached refs' , ( ) => {
110- const firstLeftRef = React . createRef ( ) ;
111- const firstRightRef = React . createRef ( ) ;
112- const secondRightRef = React . createRef ( ) ;
117+ const firstLeftRef = React . createRef < HTMLDivElement > ( ) ;
118+ const firstRightRef = React . createRef < HTMLDivElement > ( ) ;
119+ const secondRightRef = React . createRef < HTMLDivElement > ( ) ;
113120
114121 const { rerender } = render (
115122 < Div leftRef = { firstLeftRef } rightRef = { firstRightRef } id = 'test' />
116123 ) ;
117124
118125 expect ( console . error ) . not . toHaveBeenCalled ( ) ;
119126
120- expect ( firstLeftRef . current . id ) . toBe ( 'test' ) ;
121- expect ( firstRightRef . current . id ) . toBe ( 'test' ) ;
127+ expect ( firstLeftRef . current ? .id ) . toBe ( 'test' ) ;
128+ expect ( firstRightRef . current ? .id ) . toBe ( 'test' ) ;
122129 expect ( secondRightRef . current ) . toBe ( null ) ;
123130
124131 rerender (
125132 < Div leftRef = { firstLeftRef } rightRef = { secondRightRef } id = 'test' />
126133 ) ;
127134
128- expect ( firstLeftRef . current . id ) . toBe ( 'test' ) ;
135+ expect ( firstLeftRef . current ? .id ) . toBe ( 'test' ) ;
129136 expect ( firstRightRef . current ) . toBe ( null ) ;
130- expect ( secondRightRef . current . id ) . toBe ( 'test' ) ;
137+ expect ( secondRightRef . current ? .id ) . toBe ( 'test' ) ;
131138 } ) ;
132139 } ) ;
133140} ) ;
0 commit comments