Bonjour à tous,
Je dois extraire les données d'une base de donnée pour afficher des graphiques.
Je dois aussi ajouter deux boutons pour ouvrir un calendreir afin de sélectionner une date de début et une date de fin pour avoir des graphiques entre ces deux dates. Pour cela, j'essaye react-native-modal-datetime-picker ainsi que dayjs pour formater mes dates
Il faut savoir qu'une station peut être arretée et que la dernière mesure prise peut etre ancinne de 1 ou 2 mois. La date par dfaut des deux calendriers, doit correspondre à la date de la dernière mesure prise.
Le premier problème que j'ai, c'est que lorsque je charge ma page (tabs)/station/[id].tsx, les dates dateFrom et dateTo sont incunnue. Je défini une date très ancinne
Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 const [dateFrom, setDateFrom] = useState('1900-01-01'); // TODO new Date(dayjs("2025-05-01").format("YYYY-MM-DD") const [dateTo, setDateTo] = useState('1900-01-01');
Puis je fais une requete sur ma base de donnée pour avoir des informations sur ma station et les mesures enregistrées. Je connais ainsi la date de la dernière mesure
Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 const params = useLocalSearchParams() as {id: string}; const {data, isFetching} = useFetchQuery("/getstation/[id]/[from]/[to]", {id: params.id, from: dateFrom, to: dateTo}) const measures = data?.stations?.[0].measures const station = data?.stations?.[0] console.log(station?.latest_measure)
Je dois donc maintenant mettre à jour mon état
Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 if(station?.latest_measure != undefined){ setDateTo(dayjs(station?.latest_measure).format("YYYY-MM-DD")) }
Le problème est que expo affiche cette erreur
Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
Je pesne que
- setDateFrom
- useFetchQuery
- et re- setDateFrom
Génère un re-render
Comment feriez-vous pour éviter cet erreur?
A ce niveau
Peut-on de ne pas faire un render?
Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 if(station?.latest_measure != undefined){ setDateTo(dayjs(station?.latest_measure).format("YYYY-MM-DD")) }
Par exemple, est-ce que le premier render puisse etre effectué après ceci
Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 const params = useLocalSearchParams() as {id: string}; const {data, isFetching} = useFetchQuery("/getstation/[id]/[from]/[to]", {id: params.id, from: dateFrom, to: dateTo}) const measures = data?.stations?.[0].measures const station = data?.stations?.[0] console.log(station?.latest_measure)
Ou est-ce possible de faire un render juste avant le return qui contient le DOM
useQuery
Aussi, je pose vraiment la question, si ma manière de faire un useQuery est bien formulée. (J'ai suivi un tuto)
fait appel à cette fonction que j'ai un peu noettoyer pour vous facilité la lecture
Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 const params = useLocalSearchParams() as {id: string}; const {data, isFetching} = useFetchQuery("/getstation/[id]/[from]/[to]", {id: params.id, from: dateFrom, to: dateTo})
Je me demande comment je pourrai optimiser ceci surtout parce que dès que les dates 'dateFrom' et 'dateTo' devront refaire un useFetchQuery pour recharger les mesures entre les dates sélectionnées
Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 import { QueryClient, useInfiniteQuery, useQuery } from '@tanstack/react-query' const endpoint = "https://api.eco-sensors.ch/dashboard" type API = { '/getstation/[id]/[from]/[to]': { response: number, id: number, method: string, next: string | null, fields: { id_field: number, field_name: string, field_longname: string, field_city: string, field_lat: number, field_lng: number }[], stations: { id_field: number, field_name: string, id_station: number, station_longname: string, id_station_type: number, station_type_name: string, station_archive: number, lat: number, lng: number, alt: number, measures?: { datasets?: { data?:{ value: number, label: string, date: string, dataPointText: number }[], label: string, showLine:boolean, borderColor:string, backgroundColor:string, pointStyle:string, fill:boolean, borderWidth:number, pointRadius:number, type:string, }, labels: {}[], unit: string, chartContainer: string, id_sensor_type: number, id_sensor:number, sensor_type: string, sensor_type_longname: string, sensor_type_awe: string, }[], measures_found: number, station_found: number, latest_measure: string, }[], map_center:{ lat: number, lng: number, }, } } export function useFetchQuery<T extends keyof API>(path: T, params?: Record<string, string | number>){ const localurl = endpoint + Object.entries(params ?? {}).reduce((acc, [key, value]) => acc.replaceAll(`[${key}]`, value.toString()) as T, path) return useQuery({ queryKey: [localurl], //refetchIntervalInBackground: true, //refetchInterval: 60000, // 60 000 ms = 60 secondes //refetchOnWindowFocus: false, //staleTime:60000, queryFn: async () => { // Comment on reécupère les résultat //await wait(2); return fetch(localurl,{ headers:{ Accept: 'application/json', } }).then((r) => r.json() as Promise<API[T]>); // Convertir le résultat (r) en json }, }) } function wait (duration: number){ return new Promise((resolve) => setTimeout(resolve, duration * 1000)) }
merci pour votre précieuse aide
Partager