|
1 | | -import React from 'react' |
| 1 | +import React, { useCallback } from 'react' |
2 | 2 | import { render } from '@testing-library/react' |
3 | 3 | import { useInView } from '../useInView' |
4 | 4 | import { intersectionMockInstance, mockAllIsIntersecting } from '../test-utils' |
@@ -83,3 +83,75 @@ test('inView should be false when component is unmounted', () => { |
83 | 83 | rerender(<HookComponent unmount />) |
84 | 84 | getByText('false') |
85 | 85 | }) |
| 86 | + |
| 87 | +const SwitchHookComponent = ({ options, toggle, unmount }) => { |
| 88 | + const [ref, inView] = useInView(options) |
| 89 | + return ( |
| 90 | + <> |
| 91 | + <div |
| 92 | + data-testid="item-1" |
| 93 | + data-inview={!toggle && inView} |
| 94 | + ref={!toggle && !unmount ? ref : undefined} |
| 95 | + /> |
| 96 | + <div |
| 97 | + data-testid="item-2" |
| 98 | + data-inview={!!toggle && inView} |
| 99 | + ref={toggle && !unmount ? ref : undefined} |
| 100 | + /> |
| 101 | + </> |
| 102 | + ) |
| 103 | +} |
| 104 | + |
| 105 | +/** |
| 106 | + * This is a test for the case where people move the ref around (please don't) |
| 107 | + */ |
| 108 | +test('should handle ref removed', () => { |
| 109 | + const { rerender, getByTestId } = render(<SwitchHookComponent />) |
| 110 | + mockAllIsIntersecting(true) |
| 111 | + |
| 112 | + const item1 = getByTestId('item-1') |
| 113 | + const item2 = getByTestId('item-2') |
| 114 | + |
| 115 | + // Item1 should be inView |
| 116 | + expect(item1.getAttribute('data-inview')).toBe('true') |
| 117 | + expect(item2.getAttribute('data-inview')).toBe('false') |
| 118 | + |
| 119 | + rerender(<SwitchHookComponent toggle />) |
| 120 | + mockAllIsIntersecting(true) |
| 121 | + |
| 122 | + // Item2 should be inView |
| 123 | + expect(item1.getAttribute('data-inview')).toBe('false') |
| 124 | + expect(item2.getAttribute('data-inview')).toBe('true') |
| 125 | + |
| 126 | + rerender(<SwitchHookComponent unmount />) |
| 127 | + |
| 128 | + // Nothing should be inView |
| 129 | + expect(item1.getAttribute('data-inview')).toBe('false') |
| 130 | + expect(item2.getAttribute('data-inview')).toBe('false') |
| 131 | + |
| 132 | + // Add the ref back |
| 133 | + rerender(<SwitchHookComponent />) |
| 134 | + mockAllIsIntersecting(true) |
| 135 | + expect(item1.getAttribute('data-inview')).toBe('true') |
| 136 | + expect(item2.getAttribute('data-inview')).toBe('false') |
| 137 | +}) |
| 138 | + |
| 139 | +const MergeRefsComponent = ({ options }) => { |
| 140 | + const [inViewRef, inView] = useInView(options) |
| 141 | + const setRef = useCallback( |
| 142 | + (node) => { |
| 143 | + inViewRef(node) |
| 144 | + }, |
| 145 | + [inViewRef], |
| 146 | + ) |
| 147 | + |
| 148 | + return <div data-testid="inview" data-inview={inView} ref={setRef} /> |
| 149 | +} |
| 150 | + |
| 151 | +test('should handle ref merged', () => { |
| 152 | + const { rerender, getByTestId } = render(<MergeRefsComponent />) |
| 153 | + mockAllIsIntersecting(true) |
| 154 | + rerender(<MergeRefsComponent />) |
| 155 | + |
| 156 | + expect(getByTestId('inview').getAttribute('data-inview')).toBe('true') |
| 157 | +}) |
0 commit comments