如何在Reactjs中从多个输入字段处理多个onChange函数

时间:2019-01-04 21:16:03

标签: reactjs

我有一个包含5个输入文本类型字段和一个输入文件类型字段的表单。我使用了onChange函数。

这是表格

<form onSubmit ={this.onSubmit.bind(this)} >
            <FormGroup bssize="sm">
                <input onChange={this.handleChange} className="form-control" type="text" placeholder="Company Name" name="companyName" ref="companyName"/>
            </FormGroup>
            <FormGroup bssize="sm">
                <input onChange={this.handleChange} className="form-control" type="text" placeholder="Account Name" name="AccountName" ref="AccountName" />
            </FormGroup>
            <FormGroup bssize="sm">
                <input onChange={this.handleChange} className="form-control" type="text" placeholder="Bank Name" name="bankName" ref="bankName"/>
            </FormGroup>
            <FormGroup bssize="sm">
                <input onChange={this.handleChange} className="form-control" type="text" placeholder="Branch" name="branch" ref="branch"/>
            </FormGroup>
            <FormGroup bssize="sm">
                <input onChange={this.handleChange} className="form-control" type="text" placeholder="Account Number" name="accountNo" ref="accountNo"/>
            </FormGroup>
<FormGroup>

            <span>Bank Book Copy</span>  &nbsp; 
            <input style={{display :'none'}} type="file" onChange={this.fileSelectedHandler} ref={fileInput => this.fileInput = fileInput } />
            <Button onClick={()=>this.fileInput.click()} >
                  <Icon type="upload" /> Click to upload
            </Button>
            </FormGroup>
                <input onClick={this.fileUploadHandler} className="btn btn-primary" bsstyle="success" name="submit" type="submit" value="Submit" />
            </form>

现在我的问题是哪个文件最后仅填充到我的API中。我使用AXIOS进行HTTP请求。 我使用存储连接器上传图片

下面我提到了我的onChange函数

constructor(props){
        super(props);
        this.state = {
            companyName : '',
            AccountName : '',
            bankName : '' , 
            bankBookCpy : '' ,
            accountNo : '' ,
            branch : '' , 
            BankList : '',
            selectedFile : null,
        }
    }

    fileSelectedHandler = event =>{
        this.setState({
            selectedFile: event.target.files[0]
        })

    }
    handleChange = event => {
        this.setState({ 
            companyName: event.target.value,
            AccountName: event.target.value,
            bankName: event.target.value,
            accountNo: event.target.value,
            branch: event.target.value
         });

    }
    fileUploadHandler = () => {
        const fd = new FormData();
        fd.append('image',this.state.selectedFile, this.state.selectedFile.name )
        axios.post('http://localhost:3000/api/attachmentBanks/bankBookCpy/upload',fd , {
            onUploadProgress : ProgressEvent => {
                console.log('Upload Progress: ' + Math.round(ProgressEvent.loaded / ProgressEvent.total *100) + '%')
            }
        })
        .then(res => {
            this.setState({
                BankList: res.data.result.files.image[0].name,
            });

        });
    }

    AddMeetup(newMeetup){
        axios.request({
            method:'post',
            url:'http://localhost:3000/api/companyBankDetails',
            data : newMeetup
        }).then(response => {
            this.props.history.push('/');
        }).catch(err => console.log(err));
    onSubmit(e){
        const newMeetup = {
            companyName: this.state.companyName,
            AccountName : this.state.AccountName,
            bankName : this.state.bankName,
            branch : this.state.branch,
            accountNo : this.state.accountNo,
            bankBookCpy : this.state.BankList
        }
        this.AddMeetup(newMeetup);
        e.preventDefault();
    }

以上功能仅存储最后一个onChange值

4 个答案:

答案 0 :(得分:4)

您可以这样处理:

  handleChange = event => {
    this.setState({ [event.target.name]: event.target.value });
  };

答案 1 :(得分:2)

首先将handleChange函数更改为以下内容:

handleChange = name => event => {
    this.setState({ [name]: event.target.value} );
}

然后将您的name参数发送到onChange函数:

<form onSubmit ={this.onSubmit.bind(this)} >
    {
        Object.entries({
            "Company Name": "companyName",
            "Account Name": "AccountName",
            "Bank Name": "bankName",
            "Branch": "branch",
            "Account Number": "accountNo"
        }).map(([field, name]) => 
        <FormGroup bssize="sm" key={name}>
                <input onChange={this.handleChange(name)} className="form-control" type="text" placeholder={field} name={name} ref={name}  />
        </FormGroup>)
    }
<FormGroup>

您还可以通过映射数组来创建表单来避免代码重复

答案 2 :(得分:1)

正如SakoBu回答的那样,该方法可以解决您的问题。 我注意到的一件事是,您正在将ref分配给每个输入字段,而不必这样做。

请记住,如果输入类型为复选框,则通过event.taget.checked将获得相应的值。

按event.target.type检查事件类型始终是一个好习惯。

有关更多详细信息,请访问:- https://reactjs.org/docs/forms.html

希望这会有所帮助,

干杯!

答案 3 :(得分:1)

这是您的问题,是您在每个onChange事件上调用相同的handleChange()函数。假设您更改“公司名称”输入字段。更改后,您将调用handleChange()函数。然后在该函数中,将event.target.value分配给所有字段(companyName,AccountName等)。但是event.target.value仅提供您要更改的字段中的数据,以调用handleChange()方法,在这种情况下,它是“公司名称”输入。因此,这会将所有表单数据状态替换为您在“公司名称”中输入的文本。

因此,最困难的方法是可以创建单独的函数来处理每个输入字段。但这不是一个好习惯。相反,您可以按照SakoBu的回答进行操作。

该方法将从event.target.name获取状态名称,从event.target.value获取状态数据。因此,如果您更改“公司名称”的值,则handleChange()中的状态更新代码将与companyName: event.target.value,相同,但仅更改公司名称状态,而不更改其他表单状态。

您无需担心图像上传系统。因为您可以使用现有的fileUploadHandler()方法来处理文件上传的更改。