Javascript 如何在动态呈现的表单上禁用登录按钮

Javascript 如何在动态呈现的表单上禁用登录按钮,javascript,reactjs,lodash,Javascript,Reactjs,Lodash,我正在开发一个登录表单,其中每个输入都作为一个字段动态创建。 这是我的Login.js文件: import _ from 'lodash'; import React, { Component } from 'react'; import {reduxForm, Field } from 'redux-form'; import{ Link } from 'react-router-dom'; import FIELDS from './loginFields'; import Login

我正在开发一个登录表单,其中每个输入都作为一个字段动态创建。 这是我的Login.js文件:

   import _ from 'lodash';
import React, { Component } from 'react';
import {reduxForm, Field } from 'redux-form';
import{ Link } from 'react-router-dom';
import FIELDS from './loginFields';
import LoginField from './LoginField'
import { connect } from 'react-redux';
import * as actions from '../../actions'

class LoginForm extends Component {
    constructor(){
        super();
            this.state={
               username: '',
               password: ''
            };
        };

    handleChange = (e)=>{
            this.setState({username: e.target.value, password: e.target.value});
             };
    
    renderFields(){
        return _.map(FIELDS, ({ label, name, type })=> {
            return <Field onChange={this.handleChange} className='purple-text' key={name} component={ LoginField } type={type} label={label} name={name} />
        });
    };

    render(){
        const { username, password } = this.state;
        const isEnabled = username.length > 0 && password.lenth>7;
        return (
            <div className='valign-wrapper row login-box' style={{marginTop:'100px'}}>
                <div className='col card hoverable s10 pull-s1 m6 pull-m3 l4 pull-l4'>
                    <form method='POST' action='/api/login'>
                         <div className = 'card-content'>
                             <span className='card-title purple-text' style={{textAlign:'center'}}>Login<a href='/register'> Not a member? sign up!</a></span>
                             <div className='center-align row'>
                                <li key='google' style={{marginLeft: '30px'}} className='col m6 center-align white-text darken-3'><a className='white-text' href='/auth/google'><img alt="" src="https://img.icons8.com/cute-clipart/64/000000/google-logo.png"/></a></li>
                                <li key='facebook' className='col  center-align white-text darken-3'><a className='white-text' href='/auth/facebook'><img alt = "" src="https://img.icons8.com/cute-clipart/64/000000/facebook-new.png"/></a></li>
                             </div>
                                <div className='row input-field col s12'>
                                 {this.renderFields()}
                                <Link to='/' className='purple btn-flat left white-text'>Back</Link>
                                <button disabled={!isEnabled} type='submit' className='purple btn-flat right white-text'>Login
                                 <i className='material-icons right'>done</i>
                                </button>
                                
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        );
    };
};

function validate(values){
    const errors = {};

    _.each(FIELDS, ({name})=>{
        if(!values[name]){
            errors[name] = 'You must enter a value!'
        } 
    });
    return errors;
    
};

const form =  reduxForm({
    validate,
    form: 'LoginForm'
});


export default connect(null, actions)(form(LoginForm));
这里是LoginField.js

import React from 'react';

export default ({ input, label, type, meta })=>{

    return(
        <div>
            <label className='purple-text'>{label}</label>
            <input {...input} type={type} style= {{marginBottom: '5px'}}/>
            <div className = "red-text" style={{ marginBottom: '20px'}}>
                {meta.touched && meta.error}
            </div>
        </div>
            
    );
};
import React from 'react';

export default ({ name, label, type, meta, onChange, ...props })=>{

    return(
        <div>
            <label className='purple-text'>{label}</label>
            <input onChange={(e) => onChange(e, name)} {...props} type={type} style= {{marginBottom: '5px'}}/>
            <div className = "red-text" style={{ marginBottom: '20px'}}>
                {meta.touched && meta.error}
            </div>
        </div>
            
    );
};
从“React”导入React;
导出默认值({input,label,type,meta})=>{
返回(
{label}
{meta.moucted&&meta.error}
);
};
我在正确设置onChange和我的构造函数以禁用登录按钮时遇到问题,直到所有字段都被填充。我已经能够禁用按钮,直到一个单一的输入已经开始填写,没有禁用,并没有启用所有。但一直未能达到预期的效果

我尝试使用lodash映射每个字段,通过输入名称属性获取值,并移动函数


任何帮助都将不胜感激,如果我能为这个问题提供更多信息,请让我知道。

我看到的最初问题是,每当更改密码和用户名时,onChange函数都会更新它们的状态。函数接受事件,不区分哪个输入是目标。您可以从包含字段名的字段中传递附加参数,也可以检查目标的id或其他信息,以便知道应该更新哪个输入的状态

在LoginForm中

 handleChange = (e, name)=>{
    this.setState({[name]: e.target.value});
             };
您还需要将onChange回调向下传递到LoginField.js中的实际输入

import React from 'react';

export default ({ input, label, type, meta })=>{

    return(
        <div>
            <label className='purple-text'>{label}</label>
            <input {...input} type={type} style= {{marginBottom: '5px'}}/>
            <div className = "red-text" style={{ marginBottom: '20px'}}>
                {meta.touched && meta.error}
            </div>
        </div>
            
    );
};
import React from 'react';

export default ({ name, label, type, meta, onChange, ...props })=>{

    return(
        <div>
            <label className='purple-text'>{label}</label>
            <input onChange={(e) => onChange(e, name)} {...props} type={type} style= {{marginBottom: '5px'}}/>
            <div className = "red-text" style={{ marginBottom: '20px'}}>
                {meta.touched && meta.error}
            </div>
        </div>
            
    );
};
从“React”导入React;
导出默认值({name,label,type,meta,onChange,…props})=>{
返回(
{label}
onChange(e,name)}{…props}type={type}style={{{marginBottom:'5px'}}/>
{meta.moucted&&meta.error}
);
};
这是一个代码沙盒


我看到的最初问题是,每当更改密码和用户名时,onChange函数都会更新它们的状态。函数接受事件,不区分哪个输入是目标。您可以从包含字段名的字段中传递附加参数,也可以检查目标的id或其他信息,以便知道应该更新哪个输入的状态

在LoginForm中

 handleChange = (e, name)=>{
    this.setState({[name]: e.target.value});
             };
您还需要将onChange回调向下传递到LoginField.js中的实际输入

import React from 'react';

export default ({ input, label, type, meta })=>{

    return(
        <div>
            <label className='purple-text'>{label}</label>
            <input {...input} type={type} style= {{marginBottom: '5px'}}/>
            <div className = "red-text" style={{ marginBottom: '20px'}}>
                {meta.touched && meta.error}
            </div>
        </div>
            
    );
};
import React from 'react';

export default ({ name, label, type, meta, onChange, ...props })=>{

    return(
        <div>
            <label className='purple-text'>{label}</label>
            <input onChange={(e) => onChange(e, name)} {...props} type={type} style= {{marginBottom: '5px'}}/>
            <div className = "red-text" style={{ marginBottom: '20px'}}>
                {meta.touched && meta.error}
            </div>
        </div>
            
    );
};
从“React”导入React;
导出默认值({name,label,type,meta,onChange,…props})=>{
返回(
{label}
onChange(e,name)}{…props}type={type}style={{{marginBottom:'5px'}}/>
{meta.moucted&&meta.error}
);
};
这是一个代码沙盒


如果其他人遇到此问题,只需添加此项作为答案

经过大量的挖掘,我终于找到了文件。在redux表单中,有一个名为{invalid}的内置属性,它检查validate函数。我所要做的不是搞乱状态,而是添加

  const {invalid} = this.props;
在渲染方法内部。构造函数、句柄更改和onChange不再是必需的。。那么

  <button disabled={invalid}>

如果其他人遇到此问题,只需添加此作为答案即可

经过大量的挖掘,我终于找到了文件。在redux表单中,有一个名为{invalid}的内置属性,它检查validate函数。我所要做的不是搞乱状态,而是添加

  const {invalid} = this.props;
在渲染方法内部。构造函数、句柄更改和onChange不再是必需的。。那么

  <button disabled={invalid}>


刚刚注意到LoginForm的呈现函数第二行有一个输入错误--
const isEnabled=username.length>0&&password.lenth>7长度。刚刚注意到LoginForm的呈现函数第二行中有一个输入错误--
const isEnabled=username.length>0&&password.lenth>7长度。你试过这个吗?在整个表单中,无论输入的状态如何,按钮都处于禁用状态。除了我在单独的注释中提到的“长度”输入错误之外,我刚刚注意到,在LoginField.js中,您正在分解一个未定义的“输入”道具。我以为里面有名字,但名字是分开传递的。我现在已经更新了答案。我在codesandbox中尝试了它,它是有效的。我不知道为什么,但当我将{…input}更改为{…props}时,对于每个被触摸的事件,我都会抛出一个错误“onChange不是一个函数”。在这一点上,我看到的工作沙盒代码和我的代码之间的唯一区别是Login.jsi找到它的底部调用connect操作。需要参考。谢谢你的帮助!这是可行的,但替换组件会带走它带来的元道具,这些元道具会阻止我的验证功能正常运行。经过大量的挖掘,我终于找到了文件。在redux表单中,有一个名为{invalid}的内置属性,它检查validate函数。我所要做的不是搞乱状态,而是添加const{invalid}=this.props;在render方法中,那么您是否尝试过此方法?在整个表单中,无论输入的状态如何,按钮都处于禁用状态。除了我在单独的注释中提到的“长度”输入错误之外,我刚刚注意到,在LoginField.js中,您正在分解一个未定义的“输入”道具。我以为里面有名字,但名字是分开传递的。我现在已经更新了答案。我在codesandbox中尝试了它,它是有效的。我不知道为什么,但当我将{…input}更改为{…props}时,对于每个被触摸的事件,我都会抛出一个错误“onChange不是一个函数”。在这一点上,我看到的工作沙盒代码和我的代码之间的唯一区别是Login.jsi找到它的底部调用connect操作。需要参考。谢谢你的帮助!这是可行的,但替换组件会带走它带来的元道具,这些元道具会阻止我的验证功能正常运行