在react中的异步await块中的setState挂钩之后获取最新的状态值

Sus*_*mit 5 javascript setinterval async-await reactjs react-hooks

useEffect我有一个下拉菜单,当更改时调用 api 使用钩子获取数据:

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>
Run Code Online (Sandbox Code Playgroud)

我有另一个useEffect钩子,它调用另一个返回扫描状态的 api

useEffect(() => {
  fetchCompliances();

  let intervalId;

  getScanStatus(0);
  fetchFullReport();

  intervalId = setInterval(() => {
    getScanStatus(intervalId);
  }, 10000);

  return () => {
    componentDidUnmount.current = true;
    clearInterval(intervalId);
  };
}, []);
Run Code Online (Sandbox Code Playgroud)

这是获取扫描状态的函数:

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();
        }
      }
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

现在发生的是当页面加载fetchFullReport();呈现表格时。现在,当下拉列表更改时fetchReportByCompliance();,会调用过滤表,并且表现在会用更少的行进行更新。

同时,getScanStatus每隔 10 秒间隔调用一次,一旦 api 返回status = 'COMPLETED'并且间隔停止,表就会使用新数据 ( fetchFullReport();) 进行更新,并且所有表行都会返回,这是一种奇怪的行为,因为下拉过滤器仍然选择了其他选项比ALL选项。因此,当扫描完成更新表后新数据到达时,我添加了一个 if 条件来根据selectedComplianceFilter值更新表。

但是,当getScanStatus函数 api 返回 status = 'COMPLETED' 时, 的值selectedComplianceFilter仍然是'all',但下拉列表中选择了另一个选项。我假设这是因为async await块仍然保留以前的状态值selectedComplianceFilter

由于它是异步的,如何在将来执行selectedComplianceFilter时获取最新的状态值?getScanStatus

Ed *_*cas 1

将代码包装在一个在更改useEffect时触发的块中怎么样scanStatus?例如:

useEffect(() => {
    if (scanStatus === "COMPLETED") {
        if (selectedComplianceFilter === "all") {
            fetchFullReport();
        } else {
            fetchReportByCompliance();
        }
   }
}, [scanStatus]);
Run Code Online (Sandbox Code Playgroud)