Массив зависимостей useEffect вызывает несколько запусков - PullRequest
0 голосов
/ 03 августа 2020
const PERMITTED_NUMBER_OF_VERIFICATION_ATTEMPTS = 3
const {
  isLoading: isVerificationLoading, 
  isSucceeded: isVerificationSucceeded, 
  isFailed: isVerificationFailed, 
  error: verificationError,
  numberOfAttempts: numberOfVerificationAttempts
} = useSelector(state => state.authentication.verifyPasswordResetCode)

useEffect(() => {
  if (isVerificationCaptchaRendered && isVerificationCaptchaVerified) {
      console.log('Request has been sent #1')
      dispatch(verifyPasswordResetCode(oobCode))
  } 

  if (numberOfVerificationAttempts < PERMITTED_NUMBER_OF_VERIFICATION_ATTEMPTS) {
    console.log('Request has been sent #2')
    dispatch(verifyPasswordResetCode(oobCode))
  }
}, [dispatch, oobCode, numberOfVerificationAttempts, isVerificationCaptchaRendered, isVerificationCaptchaVerified])

useEffect(() => {
  // If the users try to verify the code as many as PERMITTED_NUMBER_OF_ATTEMPTS, render captcha and and set setIsVerificationCaptchaRendered to true.
  if (numberOfVerificationAttempts >= PERMITTED_NUMBER_OF_VERIFICATION_ATTEMPTS && isVerificationCaptchaLoaded && !isVerificationCaptchaRendered) {
    verificationCaptchaInstance.renderExplicitly()
    setIsVerificationCaptchaRendered(true)
  }

  // Everytime numberOfVerificationAttempts increases reset the captcha and set setIsVerificationCaptchaVerified to false.
  if (isVerificationCaptchaRendered) {
    verificationCaptchaInstance.reset()
    setIsVerificationCaptchaVerified(false)
  }
}, [verificationCaptchaInstance, numberOfVerificationAttempts, isVerificationCaptchaLoaded, isVerificationCaptchaRendered])

В моем приложении есть страница, которую посетит пользователь, щелкнув ссылку. Эта ссылка является ссылкой для сброса пароля. Как только пользователь посещает эту страницу, отправляется сетевой запрос, чтобы проверить, действительна ли ссылка для подтверждения / код сброса / oobCode. Если действительно, покажите форму для сброса пароля. Если нет, покажите сообщение об ошибке, указывающее, что ссылка недействительна.

До этого момента все работает без проблем! Хотя я хочу внедрить reCaptcha на эту страницу, чтобы предотвратить злоупотребление ею. Итак, каждый раз, когда пользователь открывает эту страницу, я увеличиваю numberOfVerificationAttempts. Если он больше PERMITTED_NUMBER_OF_VERIFICATION_ATTEMPTS, я хочу отображать reCaptcha.

Второй useEffect работает правильно. Если пользователь превышает лимит, я визуализирую капчу и указываю, что она отображается в состоянии, и каждый раз, когда пользователь обновляет страницу, я сбрасываю капчу.

Проблема связана с первым useEffect. Обычно пользователь может запросить подтверждение пароля до PERMITTED_NUMBER_OF_VERIFICATION_ATTEMPTS (# 2). Если numberOfVerificationAttempts превышает, пользователь может сделать запрос, если captcha проверена (# 1).

Однако каждый раз, когда я отправляю verifyPasswordResetCode(oobCode), он увеличивает numberOfVerificationAttempts в redux, что приводит к повторной визуализации useEffect , что приводит к бесконечным l oop до PERMITTED_NUMBER_OF_VERIFICATION_ATTEMPTS. Я не хочу, чтобы это случилось. Мне нужно запросить go один раз и остановиться. Если я удалю numberOfVerificationAttempts из массива зависимостей, все будет работать, и у меня больше не будет никаких проблем, но я не должен ie использовать Effect. Я должен разобраться с каким-то логом c и не могу понять, как это сделать.

Кстати, я пробовал сделать что-то вроде этого

if (isVerificationCaptchaRendered) {
  if (isVerificationCaptchaVerified) {
    console.log('Request has been sent #1')
    dispatch(verifyPasswordResetCode(oobCode))
  }
} else {
  if (numberOfVerificationAttempts < PERMITTED_NUMBER_OF_VERIFICATION_ATTEMPTS) {
    console.log('Request has been sent #2')
    dispatch(verifyPasswordResetCode(oobCode))
  }
}

Даже если useEffect отображает, потому что isVerificationCaptchaRendered истинно, а isVerificationCaptchaVerified ложно. Другого запроса он не сделает. Однако я установил isVerificationCaptchaRendered во втором useEffect, а он еще не готов (или установил true). Итак, этот оператор if тоже не сработает.

Надеюсь, я смог объяснить проблему. Дайте мне знать, если вы ничего не поняли.

...