|
| 1 | +import { cloneElement, ReactNode, useEffect, useState, Children } from 'react'; |
| 2 | +import { renderHook, render, act } from '@testing-library/react'; |
| 3 | +import { useChildrenWithRefs } from '@pkg/shared'; |
| 4 | + |
| 5 | +describe('useChildrenWithRefs', () => { |
| 6 | + test('base', () => { |
| 7 | + const hook = renderHook(() => { |
| 8 | + const [children, setChildren] = useState<ReactNode>(); |
| 9 | + const hook = useChildrenWithRefs(children); |
| 10 | + return [hook, setChildren] as const; |
| 11 | + }); |
| 12 | + |
| 13 | + expect(hook.result.current[0]).toEqual([undefined, []]); |
| 14 | + }); |
| 15 | + test('react ref', () => { |
| 16 | + const ref = jest.fn(); |
| 17 | + const App = () => { |
| 18 | + return Children.map( |
| 19 | + <div className="test" draggable={true} id="div"> |
| 20 | + 1 |
| 21 | + </div>, |
| 22 | + (child) => cloneElement(child, { ref }), |
| 23 | + ); |
| 24 | + }; |
| 25 | + const { container } = render(<App />); |
| 26 | + expect(ref).toHaveBeenCalled(); |
| 27 | + expect(container.firstChild).toHaveClass('test'); |
| 28 | + expect(container.firstChild).toHaveAttribute('draggable'); |
| 29 | + expect(ref.mock.calls[0][0]).toBe(container.firstChild); |
| 30 | + }); |
| 31 | + test('app', () => { |
| 32 | + const _refs: HTMLElement[] = []; |
| 33 | + const App = () => { |
| 34 | + const [children, setChildren] = useState<ReactNode>( |
| 35 | + <div className="foo">foo</div>, |
| 36 | + ); |
| 37 | + const [newChildren, refs] = useChildrenWithRefs(children); |
| 38 | + |
| 39 | + useEffect(() => { |
| 40 | + _refs.push(...refs); |
| 41 | + }, [refs]); |
| 42 | + |
| 43 | + return ( |
| 44 | + <> |
| 45 | + {newChildren} |
| 46 | + <button onClick={() => setChildren(<div className="bar">bar</div>)}> |
| 47 | + 切换 children |
| 48 | + </button> |
| 49 | + </> |
| 50 | + ); |
| 51 | + }; |
| 52 | + |
| 53 | + expect(_refs).toEqual([]); |
| 54 | + const { |
| 55 | + container: { firstChild }, |
| 56 | + } = render(<App />); |
| 57 | + |
| 58 | + expect(firstChild).toHaveTextContent('foo'); |
| 59 | + expect(firstChild).toHaveClass('foo'); |
| 60 | + expect(_refs.length).toBe(1); |
| 61 | + expect(_refs[0]).toBe(firstChild); |
| 62 | + |
| 63 | + _refs.length = 0; |
| 64 | + act(() => document.querySelector('button')!.click()); |
| 65 | + expect(firstChild).toHaveTextContent('bar'); |
| 66 | + expect(firstChild).toHaveClass('bar'); |
| 67 | + expect(_refs.length).toBe(1); |
| 68 | + expect(_refs[0]).toBe(firstChild); |
| 69 | + }); |
| 70 | +}); |
0 commit comments