Exemples de code
Petits schémas à glisser dans votre app. Corrigez les imports pour vos alias (j’aime @/), recoupez les versions avec votre SDK et si ça touche du natif, testez vraiment sur iOS et Android.
En-tête qui évite l’encoche
react-native-safe-area-context vous évite de peindre sous l’encoche, l’îlot dynamique ou la barre d’accueil.
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { View, Text } from 'react-native';
export function ScreenHeader({ title }: { title: string }) {
const insets = useSafeAreaInsets();
return (
<View style={{ paddingTop: insets.top, paddingHorizontal: 16 }}>
<Text style={{ fontSize: 18, fontWeight: '600' }}>{title}</Text>
</View>
);
}FlatList avec chargement et vide
Spinner au début, puis des lignes ou un vide simple que l’utilisateur comprend.
import { FlatList, Text, View, ActivityIndicator } from 'react-native';
type Item = { id: string; title: string };
export function ItemList({
data,
loading,
}: {
data: Item[];
loading: boolean;
}) {
if (loading && data.length === 0) {
return (
<View style={{ flex: 1, justifyContent: 'center' }}>
<ActivityIndicator />
</View>
);
}
if (!loading && data.length === 0) {
return (
<View style={{ flex: 1, justifyContent: 'center', padding: 24 }}>
<Text style={{ textAlign: 'center' }}>Nothing here yet.</Text>
</View>
);
}
return (
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={{ padding: 16 }}>
<Text>{item.title}</Text>
</View>
)}
/>
);
}Recherche qui attend la fin de la frappe
Debounce court pour ne pas marteler l’API à chaque touche ; nettoyage au démontage inclus.
import { useEffect, useState } from 'react';
import { TextInput } from 'react-native';
export function SearchField({ onQuery }: { onQuery: (q: string) => void }) {
const [text, setText] = useState('');
useEffect(() => {
const id = setTimeout(() => onQuery(text.trim()), 350);
return () => clearTimeout(id);
}, [text, onQuery]);
return (
<TextInput
value={text}
onChangeText={setText}
placeholder="Search"
style={{ borderWidth: 1, borderRadius: 8, padding: 12 }}
/>
);
}Tirer pour rafraîchir dans un ScrollView
RefreshControl branché sur du vrai async, et on enlève toujours le spinner même si la requête plante.
import { useCallback, useState, type ReactNode } from 'react';
import { ScrollView, RefreshControl } from 'react-native';
export function RefreshableScroll({ children }: { children: ReactNode }) {
const [refreshing, setRefreshing] = useState(false);
const onRefresh = useCallback(async () => {
setRefreshing(true);
try {
await new Promise((r) => setTimeout(r, 800));
} finally {
setRefreshing(false);
}
}, []);
return (
<ScrollView
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}
>
{children}
</ScrollView>
);
}Vous voulez l’arbre entier ou la grosse doc du helper ? C’est dans structure et utilitaires d’app.