javascript - 在异步等待 block 中的 setState 钩子(Hook)后获取最新状态值

标签 javascript reactjs async-await react-hooks setinterval

我有一个下拉列表,当更改调用 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 的钩子(Hook)
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 更新表值(value)。

但是当getScanStatus函数 api 返回 status = 'COMPLETED' 的值 selectedComplianceFilter仍然是 'all'但下拉菜单选择了另一个选项。我假设这是因为 async await仍然保留 selectedComplianceFilter 先前值的 block 状态。

如何获取 selectedComplianceFilter 的最新值状态getScanStatus将来执行,因为它是异步的?

最佳答案

将代码包装在 useEffect 中怎么样? scanStatus 时触发的方 block 变化?例如:

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

关于javascript - 在异步等待 block 中的 setState 钩子(Hook)后获取最新状态值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60320170/

相关文章:

javascript - 我无法在函数调用中使用之前通过 AJAX 请求加载的对象

javascript - 当我运行 react 应用程序时,出现错误 default.storage 不是一个函数

javascript - Rails ajax respond_to js 错误

javascript - React功能组件: can we setState on form load event

reactjs - 如何使用 Yup 验证 JSON 对象数组的单个元素

c# - 取消SemaphoreSlim.WaitAsync保持信号量锁

Javascript - 没有重复图像

javascript - 在 react 中将 FormData 从模态发送到父组件的方法

C# 任务异步等待智能卡 - UI 线程阻塞

c# - 将 await 与异步数据库调用一起使用有什么好处