具有异步功能的TextField onBlur(反应钩子)

时间:2019-07-12 02:03:47

标签: reactjs

我正在使用React钩子对“注册”页面进行编码。我希望我的应用在用户以异步方式输入用户名时验证用户名是否可用,并在异步操作过程中显示/隐藏InProgress微调框。

但是,似乎该应用程序未异步调用该函数,并且我看不到InProgress微调器。

这是主要代码。

如您所见,我将setIsLoadingPage设置为true,然后使用await关键字运行一个函数,然后将setIsLoadingPage重置为false以隐藏InProgressbar。



const Signup = props => {


  const [emailAddressIsValidError, setEmailAddressIsValidError] = useState(false);
  const [isLoadingPage, setIsLoadingPage] = useState(false);



  const handleChangeEmailValidation = (event) => {
    const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    if(!re.test(String(event.target.value).toLowerCase())){
      setEmailAddressIsValidError(true);
    }else{
      setEmailAddressIsValidError(false);
    }
  };

  const handleChangeEmailValidationOnBlur = async (event) => {
    console.log("focus... " + event.target.value);
    setIsLoadingPage(true);
    await verifyUserNameAvailable(event.target.value);
    setIsLoadingPage(false);

  };



  return (

      <Container component="main" maxWidth="xs">
        <CssBaseline/>
        <div className={classes.paper}>
          <div className={classes.progressBar} aria-busy={true}>
            {isLoadingPage ===true && <LinearProgress id="progressBar" />  }

          </div>
          <div className={classes.mainBox}>
            <form className={classes.form} noValidate>
              <Grid container spacing={2}>

                <Grid item xs={12}>
                  <TextField
                      variant="outlined"
                      required
                      fullWidth
                      id="email"
                      label="username"
                      error={emailAddressIsValidError}
                      name="email"
                      autoComplete="email"
                      onChange={handleChangeEmailValidation}
                      margin='dense'
                      onBlur={handleChangeEmailValidationOnBlur}
                  />
                </Grid>
              </Grid>
            </form>
          </div>
        </div>

        <Box mt={5}>
          <MadeWithLove/>
        </Box>
      </Container>
  );
}

export default Signup;

这是verifyUserNameAvailable的代码段。


export const verifyUserNameAvailable = (email) => {


  let i = 1;
  while(i<100000){
    i = i +1;
    console.log(i)
  }

};

在上面的代码中,我希望InProgress微调器在用户输入文本时显示,并在verifyUserNameAvailable函数完成计数后隐藏InProgress微调器。

实际上,UI会锁定并完成计数,并且不会显示InProgress微调器。

2 个答案:

答案 0 :(得分:0)

问题是verifyUserNameAvailable函数。您应该返回Promise而不是运行一段时间。如果您在函数之前使用await进行调用,则意味着该函数应返回一个Promise。

这将是类似的事情,但是您将发出您的API请求,而不是setTimeout

const verifyUserNameAvailable = (email) => new Promise(resolve => {
  setTimeout(resolve, 3000)
});

答案 1 :(得分:0)

awaitPromise对象前面写入时有效。

因此,如果要根据需要使用代码,则modifyUserNameAvailable函数必须返回Promise对象。

如果您要通过API调用来验证电子邮件,则可以这样:

const verifyUserNameAvailable = (email) => {
   //fetch or axios or something other api call returns Promise object 
   return fetch(...);
}

如果不是:

const verifyUserNameAvailable = (email) => {
   //fetch or axios or something other api call returns Promise object 
   return new Promise ((resolve) => {
      //...your verifying email logic
      const available = true; //or false. Results of email availability
      resolve(available) // 
   })
}