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

3
我有一个表单,其中包含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请求,使用storage-connector上传图像。

下面是我的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个回答

5
您可以这样处理:
  handleChange = event => {
    this.setState({ [event.target.name]: event.target.value });
  };

2

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

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

然后将您的名称参数发送到 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>

您可以通过将数组映射到表单来避免在代码中重复。

先生,问题是我还需要处理图片上传。我该怎么做? - Arebhy Sridaran
你需要一个“文件”类型的输入,你可以在event.target.value变量中找到有关图像的所有信息。你可能想要将输入类型添加到我制作的JSON中的每个字段。 - Treycos

1
作为SakoBu所回答的,这种方法可以解决你的问题。我注意到的一件事是你正在为每个输入字段分配ref,但你不需要这样做。
请记住,如果输入类型是复选框或单选按钮,则可以通过event.taget.checked获得相应的值。
检查事件类型始终是一个好习惯,可以使用event.target.type进行检查。
更多详情请访问:- https://reactjs.org/docs/forms.html 希望这有所帮助,
干杯!!

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相同,但仅更改CompanyName状态,而不是其他表单状态。
你不需要担心图片上传系统。因为你可以使用现有的fileUploadHandler()方法来处理文件上传的更改。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接