Проверка формы с помощью реакции и материала-ui

В настоящее время я пытаюсь добавить подтверждение в форму, созданную с использованием компонентов material-ui. Я работаю, но проблема в том, что способ, которым я сейчас выполняю функцию проверки, в настоящее время вызывается при каждом изменении состояния ввода (т.е. Каждой введенной букве). Тем не менее, я хочу, чтобы моя проверка выполнялась только после прекращения ввода.

Учитывая мой текущий код:

class Form extends React.Component {

    state = {open: false, email: '', password: '', email_error_text: null, password_error_text: null, disabled: true};

    handleTouchTap() {
        this.setState({
            open: true,
        });
    }

    isDisabled() {
        let emailIsValid = false;
        let passwordIsValid = false;

        if (this.state.email === "") {
            this.setState({
                email_error_text: null
            });
        } else {
            if (validateEmail(this.state.email)) {
                emailIsValid = true
                this.setState({
                    email_error_text: null
                });
            } else {
                this.setState({
                    email_error_text: "Sorry, this is not a valid email"
                });
            }
        }

        if (this.state.password === "" || !this.state.password) {
            this.setState({
                password_error_text: null
            });
        } else {
            if (this.state.password.length >= 6) {
                passwordIsValid = true;
                this.setState({
                    password_error_text: null
                });
            } else {
                this.setState({
                    password_error_text: "Your password must be at least 6 characters"
                });
            }
        }

        if (emailIsValid && passwordIsValid) {
            this.setState({
                disabled: false
            });
        }
    }

    changeValue(e, type) {
        const value = e.target.value;
        const nextState = {};
        nextState[type] = value;
        this.setState(nextState, () => {
            this.isDisabled()
        });
    }

    login() {
        createUser(this.state.email, this.state.password);
        this.setState({
            open: false
        });
    }

    render() {

        let {open, email, password, email_error_text, password_error_text, disabled} = this.state;

        const standardActions = (
            <FlatButton
                containerElement={<Link to="/portal" />}
                disabled={this.state.disabled}
                label="Submit"
                onClick={this.login.bind(this)} 
            />
        );

        return (
            <div style={styles.container}>
                <Dialog
                    open={this.state.open}
                    title="Enter Your Details to Login"
                    actions={standardActions}
                >
                    <span className="hint--right hint--bounce" data-hint="Enter in your email address">
                        <TextField
                            hintText="Email"
                            floatingLabelText="Email"
                            type="email"
                            errorText={this.state.email_error_text}
                            onChange={e => this.changeValue(e, 'email')} 
                        />
                    </span>
                    <br />
                    <span className="hint--right hint--bounce" data-hint="Enter your password">
                        <TextField
                            hintText="Password"
                            floatingLabelText="Password"
                            type="password"
                            errorText={this.state.password_error_text}
                            onChange={e => this.changeValue(e, 'password')} 
                        />
                    </span>
                </Dialog>
                <h1>VPT</h1>
                <h2>Project DALI</h2>
                <RaisedButton
                    label="Login"
                    primary={true}
                    onTouchTap={this.handleTouchTap.bind(this)} 
                />
            </div>
        );
    }
}

export default Form;

Есть ли способ, которым я могу достичь желаемой функциональности, не внося существенных изменений в код, или это нужно полностью реорганизовать?

Любая помощь будет высоко оценена

Спасибо за ваше время

Ответ 1

Должна ли произойти проверка после некоторой задержки? Решение, которое, как мне кажется, будет достаточным в большинстве ситуаций, будет заключаться в том, чтобы немного разбить ваш код. Не запускайте функцию isDisabled() в changedValue(). Вместо этого вместо этого он запускается в onBlur.

Попробуйте следующее:

<TextField
  hintText="Password"
  floatingLabelText="Password"
  type="password"
  errorText={this.state.password_error_text}
  onChange={e => this.changeValue(e, 'password')}
  onBlur={this.isDisabled} 
/>

а затем ваша функция будет выглядеть следующим образом:

changeValue(e, type) {
    const value = e.target.value;
    const nextState = {};
    nextState[type] = value;
    this.setState(nextState);
}

Ответ 2

Эта библиотека, которую я создал, заботится обо всем, что связано с проверкой полей, и оно также поддерживает компоненты material-ui...

Чтобы проверить свои поля, вам просто нужно обернуть компонент поля, и все готово... сэкономить массу усилий на управлении состоянием вручную.

<Validation group="myGroup1"
    validators={[
            {
             validator: (val) => !validator.isEmpty(val),
             errorMessage: "Cannot be left empty"
            }, ...
        }]}>
            <TextField value={this.state.value}
                       className={styles.inputStyles}
                       style={{width: "100%"}}
                       onChange={
                        (evt)=>{
                          console.log("you have typed: ", evt.target.value);
                        }


     }/>

Ответ 3

Проще всего позвонить form.reportValidity(). form можно получить, позвонив в event.currentTarget.form.

Ответ 4

Я только что опубликовал пакет npm для проверки форм. Рабочий пример можно найти на моем профиле github

Ответ 5

Текущая версия Material-UI не использует пропеллер errorText, но есть способ, который можно использовать для отображения ошибки и применения проверки к TextField в Material-UI.

Мы используем свойство error (Boolean), чтобы указать, есть ли ошибка или нет. Далее, чтобы отобразить текст ошибки, используйте свойство helperText TextField в Material-UI, просто предоставьте ему текст ошибки, который вы хотите отобразить.

Сделайте это как:

<TextField
  value={this.state.text}
  onChange={event => this.setState({ text: event.target.value })}
  error={text === ""}
  helperText={text === "" ? 'Empty!' : ' '}
/>

Ответ 6

Вы можете использовать событие текстового поля onblur. Это срабатывает, когда вход теряет фокус.