我有一个下拉菜单,当更改时会调用api以使用useEffect
挂钩获取数据:
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
状态的最新值?
如何将代码包装在useEffect
块中,当scanStatus
更改时会触发?例如:
useEffect(() => {
if (scanStatus === "COMPLETED") {
if (selectedComplianceFilter === "all") {
fetchFullReport();
} else {
fetchReportByCompliance();
}
}
}, [scanStatus]);