У меня есть раскрывающийся список, который при изменениях вызывает API для извлечения данных с использованием useEffect
hook:
const [selectedComplianceFilter, setComplianceFilter] = useState("all");
useEffect(() => {
if (selectedComplianceFilter === "all") {
fetchFullReport();
} else {
fetchReportByCompliance(selectedComplianceFilter);
}
}, [selectedComplianceFilter]);
<select
name="compliance"
className="custom-select w-auto"
onChange={e => setComplianceFilter(e.target.value)}
>
<option value="all">All</option>
{compliances.map((compliance, i) => (
<option key={i} value={compliance}>
{compliance}
</option>
))}
</select>
У меня есть еще один useEffect
хук, который вызывает другой API, который возвращает статус сканирования
useEffect(() => {
fetchCompliances();
let intervalId;
getScanStatus(0);
fetchFullReport();
intervalId = setInterval(() => {
getScanStatus(intervalId);
}, 10000);
return () => {
componentDidUnmount.current = true;
clearInterval(intervalId);
};
}, []);
Это функция для извлечения статуса сканирования:
const [scanStatus, setScanStatus] = useState("");
const [lastUpdated, setLastUpdated] = useState();
const [reports, setReports] = useState([]);
const getScanStatus = async intervalId => {
const resp = await API.get(SCAN_STATUS_URL);
if (resp && resp.status) {
const { scanStatus = "", lastModifiedDate = "" } = resp.data || {};
const isValidDate = moment(lastModifiedDate).isValid();
if (!componentDidUnmount.current) {
setScanStatus(scanStatus);
isValidDate && setLastUpdated(getFormattedDateTime(lastModifiedDate));
if (scanStatus === "COMPLETED") {
clearInterval(intervalId);
console.log("selectedComplianceFilter", selectedComplianceFilter); // <== returns old state i.e., 'all' but should be latest selected option.
if (selectedComplianceFilter === "all") {
fetchFullReport();
} else {
fetchReportByCompliance();
}
}
}
}
};
Теперь, когда происходит загрузка страницы, fetchFullReport();
отображает таблицу. Теперь, когда раскрывающийся список изменяется, вызывается fetchReportByCompliance();
для фильтрации таблицы, и таблица обновляется с меньшим количеством строк.
Между тем getScanStatus
вызывается через каждые 10 секунд, и как только API возвращает status = 'COMPLETED'
, интервал останавливается, и таблица обновляется новыми данными (fetchFullReport();
) и всеми строками таблицы. вернулись, что является странным поведением, так как выпадающий фильтр все еще имеет выбранный параметр, отличный от ALL
Поэтому, когда новые данные поступают, как только сканирование завершено для обновления таблицы, я добавил условие if для обновления таблицы на основе значения selectedComplianceFilter
.
Но когда функция getScanStatus
api возвращает status = 'COMPLETED', значение selectedComplianceFilter
по-прежнему равно 'all'
, но в раскрывающемся меню выбрана другая опция. Я предполагаю, что это из-за блока async await
, который все еще содержит предыдущее значение состояния selectedComplianceFilter
.
Как получить последнее значение состояния selectedComplianceFilter
, когда getScanStatus
выполняется в будущем, поскольку оно асинхронно?