开发者问题收集

如何在 React JS 中将数据作为对象数组插入

2021-06-14
2746

我的问题有点复杂,我正在构建一个与旅行相关的 Web 应用程序,用户可以在其中预订旅行。因此,我创建了一个函数,当用户单击 + 号时,该函数会增加旅行者的数量。调用此函数时,它会更改状态,并触发另一个函数,该函数显示表单以填写旅行者详细信息。现在,此表单是根据旅行的旅行者人数呈现的。如何在对象数组中设置该数据?

这里有一个屏幕截图指南:

在此处输入图片说明

我希望数据处于这样的状态:

travelersDetail: [{firstName: 'Farrukh', lastName:'Ayaz', address:'...', city:'Lahore'},
                  {firstName: 'Dwight', lastName:'Schrute', address:'...', city:'Scranton'},
                  {firstName: 'Micheal', lastName:'Scott', address:'...', city:'Scranton'},]

我的代码:

    // state

        state = {
            NumOfTravellers : 1,
            travelersDetail: [],        
            trip: null,
        }

    // the functions that increases the number of travelers

        handleClick = (e) =>{
            e.preventDefault();
            if(e.target.id == 'plus'){
            this.setState({NumOfTravellers: this.state.NumOfTravellers + 1 })
            
            }
            else if(e.target.id == 'minus'){
               this.state.NumOfTravellers > 1 ? this.setState({NumOfTravellers: 
               this.state.NumOfTravellers - 1 }) : alert("can't be less than that :)")
            }
        }

// the function that returns the traveler details form, according to the number of travelers traveling.

 const numberOfTravelers = () =>{
        var travellers = [];
        
        
        for(let t = 0; t < this.state.NumOfTravellers; t++){
          travellers.push(
            <div >
            <h4> Traveller # {t+1} Details</h4><br/>
            
            <div className="form-row">
            <div className="form-group col-md-6">
              <label htmlFor="firstName">First Name</label>
              <input type="firstName" className="form-control" onChange={this.handleTDChange} id="firstName" placeholder="FirstName" />
            </div>
            <div className="form-group col-md-6">
              <label htmlFor="lastName">Last Name</label>
              <input type="lastName" className="form-control" onChange={this.handleTDChange} id="lastName" placeholder="LastName" />
            </div>
          </div>
          <div className="form-group">
            <label htmlFor="address">Address</label>
            <input type="text" className="form-control" onChange={this.handleTDChange} id="address" placeholder="1234 Main St" />
          </div>
          <div className="form-group">
            <label htmlFor="phoneNumber">Phone Number</label>
            <input type="tel" className="form-control" onChange={this.handleTDChange} id="phoneNumber" placeholder="+92..." />
          </div>
          <div className="form-row">
            <div className="form-group col-md-6">
              <label htmlFor="city">City</label>
              <select onChange={this.handleTDChange} id="city" className="form-control">
              <option selected>Choose...</option>
              <option>Lahore</option>
              <option>Islamabad</option>
              <option>Karachi</option>
              <option>Rawalpindi</option>
              <option>Quetta</option>
              <option>Multan</option>
            </select>
            </div>
            <div className="form-group col-md-4">
              <label htmlFor="state">State</label>
              <select onChange={this.handleTDChange} id="state" className="form-control">
                <option selected>Choose...</option>
                <option>Pakistan</option>
              </select>
            </div>
            <div className="form-group col-md-2">
              <label htmlFor="zip">Zip</label>
              <input type="text" className="form-control" onChange={this.handleTDChange} id="zip" />
            </div>
          </div>    
            </div>);
          
        }
      return travellers
        
      }
2个回答

我不完全理解你的问题,我理解的是。

有一个控制器,加号和减号。单击加号时,必须添加一个新的旅行者表单,单击减号时,最后一个旅行者表单将被删除。此外,旅行者计数器会根据按钮单击而增加或减少

你不会想要 2 个变量,1 个用于跟踪旅行者人数,另一个用于存储旅行者详细信息,你只能维护 1 个变量。只要有 traverlerDetails,我们就可以从 traverlerDeterails 数组的大小中获取旅行者的数量。

// state values
this.state = {
    travelersDetail: [],
    trip: null,
};


handleClick = (clickEvent) => {
    clickEvent.preventDefault();
    const travelersDetailCopy = [...this.state.travelersDetail];
    if (e.target.id == 'plus') {
        travelersDetailCopy.push({
            firstName: '', lastName: '', address: '', city: '' // Add empty data
        });
    } else if (e.target.id == 'minus') {
        if (this.state.travelersDetail.length === 1) {
            alert("Can't be less than 1");
        } else {
            travelersDetailCopy.pop();
        }
    }
    this.setState({
        travelersDetail: travelersDetailCopy
    });
}

const numberOfTraverlers = () => {
    return this.state.travelersDetail.map((travelerDetails, index) => {
        return (
            <div key={index}>
                <h4> Traveller # {index + 1} Details</h4><br />

                <div className="form-row">
                    <div className="form-group col-md-6">
                        <label htmlFor="firstName">First Name</label>
                        <input type="firstName" className="form-control" onChange={(event) => {this.handleTDChange(event, index, "firstName")}} id="firstName" placeholder="FirstName" />
                    </div>
                    <div className="form-group col-md-6">
                        <label htmlFor="lastName">Last Name</label>
                        <input type="lastName" className="form-control" onChange={(event) => {this.handleTDChange(event, index, "lastName")}} id="lastName" placeholder="LastName" />
                    </div>
                </div>
                <div className="form-group">
                    <label htmlFor="address">Address</label>
                    <input type="text" className="form-control" onChange={(event) => {this.handleTDChange(event, index, "address")}} id="address" placeholder="1234 Main St" />
                </div>
                <div className="form-group">
                    <label htmlFor="phoneNumber">Phone Number</label>
                    <input type="tel" className="form-control" onChange={(event) => {this.handleTDChange(event, index, "phoneNumber")}} id="phoneNumber" placeholder="+92..." />
                </div>
                <div className="form-row">
                    <div className="form-group col-md-6">
                        <label htmlFor="city">City</label>
                        <select onChange={(event) => {this.handleTDChange(event, index, "city")}} id="city" className="form-control">
                            <option selected>Choose...</option>
                            <option>Lahore</option>
                            <option>Islamabad</option>
                            <option>Karachi</option>
                            <option>Rawalpindi</option>
                            <option>Quetta</option>
                            <option>Multan</option>
                        </select>
                    </div>
                    <div className="form-group col-md-4">
                        <label htmlFor="state">State</label>
                        <select onChange={(event) => {this.handleTDChange(event, index, "state")}} id="state" className="form-control">
                            <option selected>Choose...</option>
                            <option>Pakistan</option>
                        </select>
                    </div>
                    <div className="form-group col-md-2">
                        <label htmlFor="zip">Zip</label>
                        <input type="text" className="form-control" onChange={(event) => {this.handleTDChange(event, index, "zip")}} id="zip" />
                    </div>
                </div>
            </div>
        )
    })
}


handleTDChange(event, index, updateField) {
    const arrayCopy = [...this.state.travelersDetail];
    arrayCopy[index][updateField] = event.target.value;
    this.setState({travelersDetail: arrayCopy});
}

使用 this.state.travelersDetail.length 显示旅行者的数量。

不要使用 for 循环,而是使用内置函数,如 forEach、map、filter 和其他方法。

更新: 要处理 onChange 事件,您可以有多个 handleChange 事件处理程序。

但是如果您想在一个处理程序中执行此操作,您可以传递一些额外的参数。第一个是实际事件,第二个是 travelerDetails 对象的索引,第三个是需要更新的属性。

有一种更好的方法可以做到这一点,提取地图中的内容并创建一个单独的组件。它将包含与组件相关的逻辑。通过这种更新,代码的维护也容易得多

AbhishekGowda28
2021-06-14

您应该使用 javascript 中详述的 array.push() 方法将元素添加到现有数组中。

示例

const array = [];
array.push({ id: 'someId', name: 'someName' });

查看文档: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push

Vuk
2021-06-14