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:
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:
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:
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:
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:
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 lectureCode:
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:
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