Fix stale refresh usage in QueryInsightsPage effect hooks
Replaced `refresh` with `useRef` to ensure the latest value is always used in async operations. Added cleanup logic to handle component unmounts during API calls, preventing state updates on unmounted components.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { apiFetch } from "../api";
|
import { apiFetch } from "../api";
|
||||||
import { useAuth } from "../state";
|
import { useAuth } from "../state";
|
||||||
|
|
||||||
@@ -62,6 +62,7 @@ function buildQueryTips(row) {
|
|||||||
|
|
||||||
export function QueryInsightsPage() {
|
export function QueryInsightsPage() {
|
||||||
const { tokens, refresh } = useAuth();
|
const { tokens, refresh } = useAuth();
|
||||||
|
const refreshRef = useRef(refresh);
|
||||||
const [targets, setTargets] = useState([]);
|
const [targets, setTargets] = useState([]);
|
||||||
const [targetId, setTargetId] = useState("");
|
const [targetId, setTargetId] = useState("");
|
||||||
const [rows, setRows] = useState([]);
|
const [rows, setRows] = useState([]);
|
||||||
@@ -71,6 +72,10 @@ export function QueryInsightsPage() {
|
|||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
refreshRef.current = refresh;
|
||||||
|
}, [refresh]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
@@ -89,17 +94,26 @@ export function QueryInsightsPage() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!targetId) return;
|
if (!targetId) return;
|
||||||
|
let active = true;
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const data = await apiFetch(`/targets/${targetId}/top-queries`, {}, tokens, refresh);
|
const data = await apiFetch(`/targets/${targetId}/top-queries`, {}, tokens, refreshRef.current);
|
||||||
|
if (!active) return;
|
||||||
setRows(data);
|
setRows(data);
|
||||||
setSelectedQuery(data[0] || null);
|
setSelectedQuery((prev) => {
|
||||||
setPage(1);
|
if (!prev) return data[0] || null;
|
||||||
|
const keep = data.find((row) => row.queryid === prev.queryid);
|
||||||
|
return keep || data[0] || null;
|
||||||
|
});
|
||||||
|
setPage((prev) => (prev === 1 ? prev : 1));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setError(String(e.message || e));
|
if (active) setError(String(e.message || e));
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}, [targetId, tokens, refresh]);
|
return () => {
|
||||||
|
active = false;
|
||||||
|
};
|
||||||
|
}, [targetId, tokens?.accessToken, tokens?.refreshToken]);
|
||||||
|
|
||||||
const dedupedByQueryId = [...rows].reduce((acc, row) => {
|
const dedupedByQueryId = [...rows].reduce((acc, row) => {
|
||||||
if (!row?.queryid) return acc;
|
if (!row?.queryid) return acc;
|
||||||
|
|||||||
Reference in New Issue
Block a user