首页 > 解决方案 > 如何使用状态打破for循环

问题描述

我有如下代码。找到第一个匹配项时,我需要打破循环。

 const [isCodeValid, setIsCodeValid] = useState(false);
      for (let i = 0; i < properyIds.length; i++) {
        if (isCodeValid) {
          break; // this breaks it but had to click twice so state would update
        }
        if (!isCodeValid) {
          firestore().collection(`properties`)
            .doc(`${properyIds[i]}`)
            .collection('companies').get()
            .then(companies => {
              companies.forEach(company => {
                if (_.trim(company.data().registrationCode) === _.trim(registrationCode.toUpperCase())) {
                  console.log("should break here")
                  // updating state like this wont take effect right away
                  // it shows true on second time click. so user need to click twice right now. 
                  setIsCodeValid(true);   
                }
              });
            })
        }
      }

状态不会立即更新,因此if (!isCodeValid)仅适用于第二次点击。

一旦我找到匹配项,我需要更新状态或变量,以便我可以打破 for 循环。

我尝试使用一个变量,但它的值在最终 if 条件下也没有改变,我想知道是什么原因?谁能解释一下?

标签: javascriptreact-nativereact-hooks

解决方案


尝试这样的事情:

import { useState } from 'react';

function YourComponent({ properyIds }) {
  const [isCodeValid, setIsCodeValid] = useState(false);

  async function handleSignupClick() {
    if (isCodeValid) {
      return;
    }

    for (let i = 0; i < properyIds.length; i++) {
      const companies = await firestore()
        .collection(`properties`)
        .doc(`${properyIds[i]}`)
        .collection('companies')
        .get();
      for (const company of companies.docs) {
        if (_.trim(company.data().registrationCode) === _.trim(registrationCode.toUpperCase())) {
          setIsCodeValid(true);
          return;
        }
      }
    }
  }

  return (<button onClick={handleSignupClick}>Sign Up</button>);
}

如果您等待这些检查,这将允许您使用简单的顺序循环和中断return,这是您无法在回调内部执行的操作。请注意,如果这是在进行数据库查询,您可能应该在此期间显示等待反馈,以便用户知道单击完成了某些操作。

更新

如果可行,您可能希望并行执行所有这些检查,这样用户就不必等待。取决于你的情况。下面是你如何做到这一点。

async function handleSignupClick() {
  if (isCodeValid) {
    return;
  }

  const allCompanies = await Promise.all(
    properyIds.map(id => firestore()
      .collection(`properties`)
      .doc(`${properyIds[i]}`)
      .collection('companies')
      .get()
    )
  );

  setIsCodeValid(
    allCompanies.some(companiesSnapshot => 
      companiesSnapshot.docs.some(company => 
        _.trim(company.data().registrationCode) === _.trim(registrationCode.toUpperCase())
      )
    )
  );
}

推荐阅读