首页 > 解决方案 > 从 signIn 切换到 signUp 时重置错误段落

问题描述

我有一个动态填充登录/注册表单的反应组件。我从服务器收到一些错误,然后我用它来显示它们

元素。我的问题是,当我在登录表单中收到错误(例如,找不到用户)然后切换到注册表单时,错误仍然显示在 UI 上。

我正在寻找一种在切换表单时清除 errorMessage 变量的方法,以便不显示消息。我已经尝试使用 componentDidUpdate(),清除错误消息状态道具,但这不允许显示注册错误消息。

下面是我的组件的副本:


class Auth extends Component {
    state = {
        controlsAuth: {
            email: {
                elementType: 'input',
                elementConfig: {
                    type: 'email',
                    placeholder: 'Your Email Address',
                },
                value: '',
                validation: {
                    required: true,
                    isEmail: true,
                },
                valid: false,
                touched: false,
            },
            password: {
                elementType: 'input',
                elementConfig: {
                    type: 'password',
                    placeholder: 'Enter New Password',
                },
                value: '',
                validation: {
                    required: true,
                    minLength: 7,
                },
                valid: false,
                touched: false,
            },
        },
        creatingAccount: false,
    };

    checkValidity(value, rules) {
        let isValid = true;
        if (!rules) {
            return true;
        }

        if (rules.required) {
            isValid = value.trim() !== '' && isValid;
        }

        if (rules.minLength) {
            isValid = value.length >= rules.minLength && isValid;
        }

        if (rules.maxLength) {
            isValid = value.length <= rules.maxLength && isValid;
        }

        if (rules.isEmail) {
            const pattern = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
            isValid = pattern.test(value) && isValid;
        }

        if (rules.isNumeric) {
            const pattern = /^\d+$/;
            isValid = pattern.test(value) && isValid;
        }

        return isValid;
    }

    inputChangedHandler = (event, controlName) => {
        const updatedAuthForm = {
            ...this.state.controlsAuth,
            [controlName]: {
                ...this.state.controlsAuth[controlName],
                value: event.target.value,
                valid: this.checkValidity(
                    event.target.value,
                    this.state.controlsAuth[controlName].validation
                ),
                touched: true,
            },
        };

        this.setState({ controlsAuth: updatedAuthForm });
    };

    submitHandler = (event) => {
        event.preventDefault();
        this.props.onAuth(
            this.state.controlsAuth.email.value,
            this.state.controlsAuth.password.value,
            this.state.creatingAccount
        );
    };

    switchAuthStatusHandler = (error) => {
        this.setState((prevState) => {
            return { creatingAccount: !prevState.creatingAccount };
        });
    };

    render() {
        const formElementsArray = [];

        for (let key in this.state.controlsAuth) {
            formElementsArray.push({
                id: key,
                config: this.state.controlsAuth[key],
            });
        }

        let authenticationForm = formElementsArray.map((inputEl) => (
            <Input
                key={inputEl.id}
                elementType={inputEl.config.elementType}
                elementConfig={inputEl.config.elementConfig}
                value={inputEl.config.value}
                invalid={!inputEl.config.valid}
                shouldValidate={inputEl.config.validation}
                touched={inputEl.config.touched}
                changed={(event) => this.inputChangedHandler(event, inputEl.id)}
            />
        ));

        if (this.props.loadingAuth) {
            authenticationForm = <Spinner />;
        }

        let errorMessage = null;

        if (this.props.errorAuth) {
            const message = this.props.errorAuth.message
                .replace(/_/g, ' ')
                .toLowerCase();
            errorMessage = (
                <p
                    className={classes.ErrorMessage}
                >{`Sorry, ${message}. Please try again`}</p>
            );
        }

        let authRedirect = null;
        if (this.props.isAuthenticated) {
            authRedirect = <Redirect to="/" />;
        }
        return (
            <div className={classes.Auth}>
                {authRedirect}
                {errorMessage}
                {this.state.creatingAccount ? <h2>Welcome to Budget World!</h2> : null}
                {authenticationForm}
                <div className={classes.BtnsHolder}>
                    <button
                        className={classes.AuthBtn}
                        onClick={(e) => {
                            this.submitHandler(e);
                        }}
                    >
                        {!this.state.creatingAccount ? 'Log In' : 'Sign Up'}
                    </button>
                </div>
                <p
                    className={classes.FormMessage}
                    onClick={this.switchAuthStatusHandler}
                >
                    {!this.state.creatingAccount
                        ? 'Register Here!'
                        : 'Already a user? Login In'}
                </p>
            </div>
        );
    }
}

const mapStateToProps = (state) => {
    return {
        errorAuth: state.authR.errorAuthentication,
        loadingAuth: state.authR.loadingAuth,
        isAuthenticated: state.authR.token !== null,
    };
};

const mapDispatchToProps = (dispatch) => {
    return {
        onAuth: (email, password, creatingAccount) =>
            dispatch(actions.auth(email, password, creatingAccount)),
    };
};

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

谢谢!

标签: javascriptreactjs

解决方案


您需要创建一个新方法,例如调用: resetFormState和另一个resetErrorMessage. 当用户登录成功时,将调用此方法。

resetFormState 方法应该这样做:

  • 使表单中的所有字段保持不变 -touched: false
  • 该方法应该调用resetErrorMessage

resetErrorMessage其一侧的方法应将 errorMessage 设置为 null。

你可以在这里调用它:switchAuthStatusHandler在改变之前creatingAccount


推荐阅读