在react的async await块内的setState钩子之后获取最新状态值

问题描述 投票:0回答:1

我有一个下拉菜单,当更改时会调用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状态的最新值?

javascript reactjs async-await react-hooks setinterval
1个回答
0
投票

如何将代码包装在useEffect块中,当scanStatus更改时会触发?例如:

useEffect(() => {
    if (scanStatus === "COMPLETED") {
        if (selectedComplianceFilter === "all") {
            fetchFullReport();
        } else {
            fetchReportByCompliance();
        }
   }
}, [scanStatus]);
© www.soinside.com 2019 - 2024. All rights reserved.