在react-redux-form中,如何禁用提交按钮,直到所有必填字段都未填满

时间:2017-11-21 12:25:07

标签: reactjs react-redux-form

处理反应应用from this tutorial,我需要一个处理表单和验证的库,并且跟随2个库的搜索结果最多

  1. redux-form
  2. react-redux-form
  3. 首先,不确定需要使用哪个,所以尝试了后面的步骤

    请查看 demo here

    1)在 reducers.js 中的createForms()中使用combineReducers

    const initialUserState = {
      firstName: '',
      lastName: '',
      userName: '',
      email: '',
      password: '',
      confirmPassword: ''
    };
    
    const rootReducer = combineReducers({
        ...createForms({
            user: initialUserState
        })
    });
    

    2)在 RegisterPage.js 中我用了和Component来创建表单

    class RegisterPage extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          user: {
            firstName: '',
            lastName: '',
            username: '',
            email: '',
            password: '',
            confirmPassword: ''
          },
          submitted: false
        };
    
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
      }
    
      handleChange(event) {
        const { name, value } = event.target;
        console.log(`handleChange called => name ${name}, value: ${value}`);
        const { user } = this.state;
        this.setState({
          user: {
            ...user,
            [name]: value
          }
        });
      }
    
      handleSubmit(user) {
        console.log("handleSubmit state", this.state);
        this.setState({ submitted: true });
        const { user } = this.state;
        console.log("user", user);
        const { dispatch } = this.props;
        dispatch(userActions.register(user));
      }
    
      render() {
        return (
          <div className="col-md-6 col-md-offset-3">
            <h2>Register</h2>
            <Form model="user" onSubmit={(user) => this.handleSubmit(user)} >
              <div className="form-group">
                <label htmlFor="firstName">First Name</label>
                <Control.text
                  id="firstName"
                  className="form-control"
                  model=".firstName"
                  onChange={this.handleChange}
                  validators={{ required: isRequired, maxLength: maxLength(50) }}
                  validateOn="blur"
                />
                <Errors
                  model=".firstName"
                  className="errors text-danger"
                  show="touched"
                  messages={{
                    required: 'Please provide First Name.',
                    maxLength: 'Maximum length can be 50 characters.'
                  }}
                />
              </div>
              <div className="form-group">
                <label htmlFor="lastName">Last Name</label>
                <Control.text className="form-control" model=".lastName" onChange={this.handleChange} />
              </div>
              <div className="form-group">
                <label htmlFor="username">Username</label>
                <Control.text className="form-control" model=".username" onChange={this.handleChange} />
              </div>
              <div className="form-group">
                <label htmlFor="firstName">Email Address</label>
                <Control.text className="form-control" model=".email" onChange={this.handleChange} />
              </div>
              <div className="form-group">
                <label htmlFor="password">Password</label>
                <Control type="password" className="form-control" model=".password" onChange={this.handleChange} />
              </div>
              <div className="form-group">
                <label htmlFor="confirmPassword">Confirm Password</label>
                <Control type="password" id="confirmPassword" className="form-control" model=".confirmPassword" onChange={this.handleChange} />
              </div>
              <div className="form-group">
                <button type="submit" className="btn btn-primary" >Register</button>
              </div>
            </Form>
          </div>
        );
      }
    }
    
    const connectedRegisterPage = connect()(RegisterPage);
    export { connectedRegisterPage as RegisterPage };
    

    当我点击提交按钮时,状态更改为&#34; USER_REGISTER_REQUEST&#34; 状态,但它会在用户数据中添加其他属性,如下所示

    user: {
    confirmPassword : ""
    email: ""
    firstName: ""
    lastName: ""
    password: ""
    user.firstName: "foo" << added extra property
    username: ""
    

    所以我的集体质疑是(请允许我在一篇文章中提出类似的问题,请求你不要进行投票,他们都是密切相关的)

    1. 当我们在this.state = { user : {} }中定义为constructor()时,为什么我们需要在RegisterPage initialUserState中再次定义combineReducer。 我并不完全理解这一点,请帮助我。

    2. 如果在所有必填字段未填满之前如何禁用提交按钮?从角度背景调用,我们使用ng-pristineng-touchedng-valid和许多其他指令来检查表单字段,并在ng-disabled中将表达式写入禁用的提交按钮。

    3. 类似的功能可以在react中实现吗?

      1. 还在控制台中检查每次不必要地调用焦点/模糊状态(type: "rrf/focus")。如何防止它们或这是正常的反应行为,一般不影响我们的页面?

      2. 为什么在提交时会在用户对象中添加其他数据?

      3. 上面哪个库更方便用户使用?

2 个答案:

答案 0 :(得分:1)

最好的办法是遵循这些图书馆的文档。两者都有关于如何创建表单的简单明了的演示。

Redux Form docs

React Redux Form docs

我对两者都有经验,我个人选择了react-redux-form,因为它有灵活性。

虽然回答你的问题 -

  1. 不,您根本不需要使用this.state来处理表单,因为它都是在redux状态下处理的。
  2. 要停用表单组件,请阅读this。它是使用Control道具
  3. disabled组件上的文档
  4. 不要担心blurfocus。那些不会影响你的表现
  5. 您已在组件模型中定义了user.firstName。请阅读模型上的this页面。
  6. 如上所述,我建议react-redux-form

答案 1 :(得分:0)

首先我使用redux .. 最简单的方法是设置disable = {invalid}。

<Button type="submit" disabled={invalid}>Submit</Button>

如果你console.log(props);

,请在道具中

你会发现许多密钥,例如无效,有效,原始,提交,提交。

它们中的大多数都具有布尔值true和false,并且随着您对表单执行操作而更改。

当我的表格无效(无效)时,无效将为真。

但填写字段时,无效变量将为false。

在这里使用它。

const SyncValidationForm = (props) => { const {handleSubmit, pristine, reset, submitting, invalid} = props; console.log(props);

将道具无效设置为使用它。

然后只需添加disable = {invalid}

但我有一个更好的简单解决方案: 做那样的事情:

disabled="{!this.state.user.lastName || !this.state.username.email || !this.state.user.password}

这将继续返回true,直到所有字段都填满