如何在Recaptcha回调中访问更新的道具

问题描述 投票:0回答:2

我正在尝试将React和Redux集成在Firebase身份验证中的reCaptcha。

const Login = props => {

    useEffect(() => {
        window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('login-button', {
                'size': 'invisible',
                'callback': () => login()
            }
        );
        window.recaptchaVerifier.render()
    }, []);

    function login() {
        console.log(props)
        firebaseLogin(props.email, props.password).then(() => {
                ...
            }
        ).catch(function (error) {
            console.log(error);
            ...
        });
    }

    function onChangePassword(event) {
        props.onChangePassword(event.target.value)
    }

    function onChangeEmail(event) {
        props.onChangeEmail(event.target.value)
    }

    return (
        ...
            <form>
                <label>Dirección de Email</label>

                <div className="form-group">
                    <input type="email"
                           className={`form-control ${emailValidation ? "is-invalid" : ""}`}
                           placeholder="[email protected]"
                           onChange={onChangeEmail} value={props.email} tabIndex={1}
                           autoComplete={"username"}
                           required/>
                    <div className="invalid-feedback">
                        {emailValidation}
                    </div>

                </div>

                <div className="form-group">

                    <div className="row">
                        <div className="col">

                            <label>Contraseña</label>

                        </div>
                        <div className="col-auto">

                            <Link to="/reset-password" className="form-text small text-muted">
                                Olvidé mi contraseña
                            </Link>

                        </div>
                    </div>

                    <div className="input-group input-group-merge">

                        <input type={showPassword ? "text" : "password"}
                               className={`form-control ${passwordValidation ? "is-invalid" : ""} form-control-appended`}
                               placeholder="Ingrese su contraseña" onChange={onChangePassword}
                               value={props.password} required tabIndex={2}
                               autoComplete={"current-password"}/>

                        <div className="input-group-append">
                      <span className="input-group-text clickable"
                            onClick={() => setShowPassword(!showPassword)}>
                        <i className="fe fe-eye"/>
                      </span>
                        </div>
                        <div className="invalid-feedback">
                            {passwordValidation}
                        </div>

                    </div>
                </div>

                <button type="submit" className="btn btn-lg btn-block btn-primary mb-3"
                        id={"login-button"}
                        tabIndex={3}>
                    Acceder
                </button>
            </form>
        ...
    )
};

const mapDispatchToProps = dispatch => ({
    onChangeEmail: value =>
        dispatch({type: UPDATE_LOGIN_FIELD, key: 'formEmail', value}),
    onChangePassword: value =>
        dispatch({type: UPDATE_LOGIN_FIELD, key: 'password', value}),
});

const mapStateToProps = state => ({
    email: state.authentication.formEmail,
    password: state.authentication.password,
});

export default connect(mapStateToProps, mapDispatchToProps)(Login);

问题是,在登录回调中,道具已经过时,并且不包含在redux存储中加载的电子邮件和密码,它仅包含触发useEffect时可用的道具。 (我通过console.log(props)看到了)

我不知道如何保留对更新道具的引用。我尝试使用useRef挂钩并将其作为参数发送到登录名,但这也不起作用。

我也尝试过使用电子邮件和密码道具作为useEffect依赖项,但是这多次触发了Recaptcha生成,而且效率很低。

感谢您的帮助!

javascript reactjs redux firebase-authentication recaptcha
2个回答
1
投票

使用回调挂钩以高性能的方式访问最新状态。

    const login = useCallback( () => {
        console.log(props)
        firebaseLogin(props.email, props.password).then(() => {
                ...
            }
        ).catch(function (error) {
            console.log(error);
            ...
        });
    }, [ props ] ):

在官方的React文档上,它声明:“传递一个内联回调和一系列依赖项。useCallback将返回该回调的记录版本,只有在其中一个依赖项发生更改时,该回调版本才会更改。”在我们的例子中,每次[props]更改时,登录功能都会自动更新,这意味着当我们获得新的道具时,我们将获得一个新的登录功能。

查看官方hook documentation,以获取有关如何使用哪个钩子的更多信息。

您甚至可以将useCallback用于所有三个功能!

    const onChangePassword = useCallback( (event) => {
        props.onChangePassword(event.target.value)
    }, [props.onChangePassword]);

    const onChangeEmail = useCallback( (event) => {
        props.onChangeEmail(event.target.value)
    }, [props.onChangeEmail]);

onChangePasswordonChangeEmail回调函数将在每次从Redux或更高阶组件更新props.onChangePasswordprops.onChangeEmail函数时更新并创建新函数。


0
投票

似乎起

window.login = useCallback(() => {
        console.log(props);
        firebaseLogin(props.email, props.password).then(() => {
             ...
            }
        ).catch(function (error) {
            console.log(error);
            ....
            }
    }, [props]);

useEffect(() => {
        window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('login-button', {
                'size': 'invisible',
                'callback': () => window.login(),
            }
        );
        window.recaptchaVerifier.render();
    }, []);

还有另一个问题,但与此问题无关

© www.soinside.com 2019 - 2024. All rights reserved.