【问题标题】:Form validation with react and material-ui使用 react 和 material-ui 进行表单验证
【发布时间】:2016-08-23 01:06:24
【问题描述】:

我目前正在尝试向使用 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;

有没有一种方法可以实现我想要的功能,而无需对代码进行重大更改,还是需要对其进行完全重构?

【问题讨论】:

标签: validation events reactjs material-ui


【解决方案1】:

当前 Material-UI 版本不使用 errorText 属性,但仍有一种方法可用于显示错误并将验证应用于 Material-UI 中的 TextField。

我们使用error(Boolean) 属性来表示是否存在错误。要进一步显示错误文本,请使用 Material-UI 中 TextField 的 helperText 属性,只需提供您要显示的错误文本即可。

这样做:

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

【讨论】:

    【解决方案2】:

    最简单的方法是致电form.reportValidity()form可以通过调用event.currentTarget.form获取。

    【讨论】:

      【解决方案3】:

      我创建的这个library 负责所有与验证字段相关的事情,它还支持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);
                              }
      
      
           }/>
      

      【讨论】:

      • 如果你要推广你自己的库,你必须声明它——见Stack Overflow behaviour
      • 我已经编辑了答案,感谢您的审核和指出。
      【解决方案4】:

      检查是否必须在一定延迟后进行?我认为在大多数情况下就足够的解决方案是将您的代码拆分一下。不要在changedValue() 中触发您的isDisabled() 函数。而是让它在 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);
      }
      

      【讨论】:

      • 目前没有延迟,所以在满足验证参数之前会显示错误消息,但我想在之后进行检查。
      • 之后具体是什么时候?我上面的答案将检查用户何时“离开”文本框。这不是你要找的吗?
      • onBlur 没有这样做 isDisabled 永远不会因为某种原因被调用,我认为这意味着 onBlur 事件没有触发??
      • 这给了我一个错误 Uncaught TypeError: Cannot read property 'email' of undefined
      • 是的,我修好了,把 this.setState({nextState: nextState}) 改成了 this.setState(nextState);现在一切正常!感谢您的所有帮助!
      【解决方案5】:

      您可以使用 onblur 文本字段事件。当输入失去焦点时触发。

      【讨论】:

      • 虽然您的建议可行,但最好在每次击键时更新值,但改为进行验证 onblur。
      猜你喜欢
      • 2020-08-06
      • 1970-01-01
      • 2021-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-17
      • 2021-02-01
      相关资源
      最近更新 更多