({
next,
hasMore,
children,
loader,
scrollThreshold = 0.8,
endMessage,
style,
height,
scrollableTarget,
hasChildren,
inverse = false,
pullDownToRefresh = false,
pullDownToRefreshContent,
releaseToRefreshContent,
pullDownToRefreshThreshold = 100,
refreshFunction,
onScroll,
dataLength,
initialScrollY,
className = '',
role,
tabIndex,
id,
...ariaProps
}: Props)
| 128 | } |
| 129 | |
| 130 | export default function InfiniteScroll({ |
| 131 | next, |
| 132 | hasMore, |
| 133 | children, |
| 134 | loader, |
| 135 | scrollThreshold = 0.8, |
| 136 | endMessage, |
| 137 | style, |
| 138 | height, |
| 139 | scrollableTarget, |
| 140 | hasChildren, |
| 141 | inverse = false, |
| 142 | pullDownToRefresh = false, |
| 143 | pullDownToRefreshContent, |
| 144 | releaseToRefreshContent, |
| 145 | pullDownToRefreshThreshold = 100, |
| 146 | refreshFunction, |
| 147 | onScroll, |
| 148 | dataLength, |
| 149 | initialScrollY, |
| 150 | className = '', |
| 151 | role, |
| 152 | tabIndex, |
| 153 | id, |
| 154 | ...ariaProps |
| 155 | }: Props) { |
| 156 | const [showLoader, setShowLoader] = useState(false); |
| 157 | const [pullToRefreshThresholdBreached, setPullToRefreshThresholdBreached] = |
| 158 | useState(false); |
| 159 | // State drives the JSX re-render when height is measured; ref is read by handlers |
| 160 | const [maxPullDownDistance, setMaxPullDownDistance] = useState(0); |
| 161 | |
| 162 | const infScrollRef = useRef<HTMLDivElement>(null); |
| 163 | const sentinelRef = useRef<HTMLDivElement>(null); |
| 164 | const pullDownRef = useRef<HTMLDivElement>(null); |
| 165 | |
| 166 | // --- Stable callback refs --- |
| 167 | // Assigned synchronously every render so effects and event handlers always call |
| 168 | // the latest version without adding the functions to any effect dependency array. |
| 169 | // This prevents the IO observer and PTR listeners from being recreated every time |
| 170 | // consumers pass inline functions (the most common real-world usage). |
| 171 | const nextRef = useRef(next); |
| 172 | nextRef.current = next; |
| 173 | |
| 174 | const refreshFunctionRef = useRef(refreshFunction); |
| 175 | refreshFunctionRef.current = refreshFunction; |
| 176 | |
| 177 | // Ref for pullDownToRefreshThreshold so onMove always reads the current value |
| 178 | // without needing it in the PTR effect deps |
| 179 | const pullThresholdRef = useRef(pullDownToRefreshThreshold); |
| 180 | pullThresholdRef.current = pullDownToRefreshThreshold; |
| 181 | |
| 182 | // --- Mutable refs — never trigger re-renders --- |
| 183 | const actionTriggeredRef = useRef(false); |
| 184 | const draggingRef = useRef(false); |
| 185 | const startYRef = useRef(0); |
| 186 | const currentYRef = useRef(0); |
| 187 | const maxPullDownDistanceRef = useRef(0); // kept in sync with maxPullDownDistance state |
nothing calls this directly
no test coverage detected
searching dependent graphs…