Home > Blockchain >  Maximum update depth exceeded error in react app
Maximum update depth exceeded error in react app

Time:04-08

I am getting this error when trying to type a password longer than 6 characters in the following react form

Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

for each character the user inputs in password/confirm password, I need to validate them.

How can I do this avoiding this infinite loop?

export const Signup: FC<InjectedFormProps<string>> = (props) => {
    const {handleSubmit} = props
    const {t} = useTranslation()
    const [password, setPassword] = useState();
    const [confirmPassword, setConfirmPassword] = useState();
    const [isValid, setValidity] = useState(false);
    const errorMessage = useSelector(getErrorMessage)

    const onChangePassword = (event: any) => {
        setPassword(event.target.value)
    }

    const onChangeConfirmPassword = (event: any) => {
        setConfirmPassword(event.target.value)
    }

    const validatePasswords = () => {
        if (password && confirmPassword) {
            setValidity(password === confirmPassword)
        }
    }

    useEffect(() => {
        validatePasswords();
    }, [password, confirmPassword, isValid])

    const minLength = minLengthPassword(6)

    return (
        <form onSubmit={handleSubmit}>
            <FRow className="full-width">
                <FGroup>
                    <Field validate={minLength} onChange={onChangePassword} name="password" component="input" type="password" placeholder="Password"/>
                </FGroup>
            </FRow>
            <FRow className="full-width">
                <FGroup>
                    <input onChange={onChangeConfirmPassword} name="confirmPassword" type="password" placeholder="Confirm Password"/>
                </FGroup>
            </FRow>
            <FRow>
                {isValid ? '' : <Error>{t("auth.lbl_passwords_must_match")}</Error>}
            </FRow>
            <FullWidthSvgButton disabled={!isValid}>
                    <span>{t("buttons.btn_sign_up")}</span>
            </FullWidthSvgButton>

            {errorMessage && (
                <Error>{errorMessage}</Error>
            )}
        </form>
    )
}
export const SignupForm = reduxForm<any>({
    form: "Signup",
})(Signup)
export default SignupForm

CodePudding user response:

Try to remove isValid from the dependencies.

useEffect(() => {
  validatePasswords();
}, [password, confirmPassword])

You should run your setValidity only when password or confirmPassword changed. If you call it when your isValid changed - you are getting the infinite loop (because setValidity changes isValid)

CodePudding user response:

Please update your hooks like the following.

Wrap validatePasswords by useCallback with dependencies of 2 states.

And add this function in dependency of useEffect.


const validatePasswords = useCallback( () => {
    if (password && confirmPassword) {
      setValidity(password === confirmPassword)
    }
  }, [password, confirmPassword])

  useEffect(() => {
    validatePasswords();
  }, [validatePasswords])

  • Related