t1k:rn:base:components
| Field | Value |
|---|---|
| Module | base |
| Version | 1.7.4 |
| Effort | medium |
| Tools | — |
Keywords: components, core components, FlatList, hooks, memo, react native
How to invoke
Section titled “How to invoke”/t1k:rn:base:componentsRN Base Components
Section titled “RN Base Components”Core Component Patterns
Section titled “Core Component Patterns”// Typed component with forwarded refimport { View, StyleSheet, ViewProps } from 'react-native';
interface CardProps extends ViewProps { title: string; onPress?: () => void;}
export const Card = memo(({ title, onPress, style, ...props }: CardProps) => ( <Pressable onPress={onPress} style={[styles.card, style]} {...props}> <Text style={styles.title}>{title}</Text> </Pressable>));
const styles = StyleSheet.create({ card: { padding: 16, borderRadius: 8, backgroundColor: '#fff' }, title: { fontSize: 16, fontWeight: '600' },});FlatList Best Practices
Section titled “FlatList Best Practices”// Always provide keyExtractor and getItemLayout when possible<FlatList data={items} keyExtractor={(item) => item.id} renderItem={({ item }) => <ItemRow item={item} />} getItemLayout={(_, index) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index })} initialNumToRender={10} maxToRenderPerBatch={10} windowSize={5} removeClippedSubviews/>Custom Hook Pattern
Section titled “Custom Hook Pattern”export function useDebounce<T>(value: T, delay: number): T { const [debounced, setDebounced] = useState(value); useEffect(() => { const timer = setTimeout(() => setDebounced(value), delay); return () => clearTimeout(timer); }, [value, delay]); return debounced;}Key Rules
Section titled “Key Rules”- Wrap all list items in
memo()— prevents re-renders on parent state changes - Use
useCallbackfor event handlers passed as props StyleSheet.create()over inline styles — processed once, not per render- Prefer
PressableoverTouchableOpacity(new API, more flexible) - Use
useWindowDimensions()for responsive sizing — notDimensions.get()
Gotchas
Section titled “Gotchas”FlatListinsideScrollViewcauses infinite height issues — usenestedScrollEnabledor restructurekeyExtractormust return unique strings — never use array index for dynamic listsmemo()only does shallow comparison — useuseMemofor derived objects passed as propsStyleSheet.absoluteFillObjectis{ position: 'absolute', top: 0, right: 0, bottom: 0, left: 0 }
Security
Section titled “Security”- Never render user-provided HTML — no
dangerouslySetInnerHTMLequivalent needed but sanitize text - Validate image URLs before passing to
<Image source={{ uri }}>— rejectjavascript:URIs