initial commit

This commit is contained in:
René Schober
2026-03-13 06:23:06 +01:00
commit 4e34270786
314 changed files with 37280 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
---
title: Never Track Scroll Position in useState
impact: HIGH
impactDescription: prevents render thrashing during scroll
tags: scroll, performance, reanimated, useRef
---
## Never Track Scroll Position in useState
Never store scroll position in `useState`. Scroll events fire rapidly—state
updates cause render thrashing and dropped frames. Use a Reanimated shared value
for animations or a ref for non-reactive tracking.
**Incorrect (useState causes jank):**
```tsx
import { useState } from "react";
import { ScrollView, NativeSyntheticEvent, NativeScrollEvent } from "react-native";
function Feed() {
const [scrollY, setScrollY] = useState(0);
const onScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
setScrollY(e.nativeEvent.contentOffset.y); // re-renders on every frame
};
return <ScrollView onScroll={onScroll} scrollEventThrottle={16} />;
}
```
**Correct (Reanimated for animations):**
```tsx
import Animated, { useSharedValue, useAnimatedScrollHandler } from "react-native-reanimated";
function Feed() {
const scrollY = useSharedValue(0);
const onScroll = useAnimatedScrollHandler({
onScroll: (e) => {
scrollY.value = e.contentOffset.y; // runs on UI thread, no re-render
},
});
return (
<Animated.ScrollView
onScroll={onScroll}
// higher number has better performance, but it fires less often.
// unset this if you need higher precision over performance.
scrollEventThrottle={16}
/>
);
}
```
**Correct (ref for non-reactive tracking):**
```tsx
import { useRef } from "react";
import { ScrollView, NativeSyntheticEvent, NativeScrollEvent } from "react-native";
function Feed() {
const scrollY = useRef(0);
const onScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
scrollY.current = e.nativeEvent.contentOffset.y; // no re-render
};
return <ScrollView onScroll={onScroll} scrollEventThrottle={16} />;
}
```