删除'this'组件onClick而不是使用pop

时间:2016-03-10 05:33:30

标签: reactjs

我有一个组件,我将通过道具传递给我创建的删除按钮组件。现在使用该函数,我只是使用pop并删除数组中的最后一个对象。显然,这不能很好地工作,我希望它是你点击该特定组件的删除按钮的地方,它就摆脱了它。

我希望能够单击单个故障单上的“删除”按钮,以便删除特定的渲染组件。你会怎么做呢?

所有门票清单

var Tickets = React.createClass({
  getInitialState: function() {
    var i = 0;
    return {
      tickets: [],
    }
  },
  createTicket: function() {
    i++;
    var newTicket = this.state.tickets
    newTicket.push(
      <IndividualTicketInput key={i} deleteTicket={this.deleteTicket} />
    )
    this.setState({newTicket});
    this.forceUpdate();
  },
  deleteTicket: function() {
    var ticket = this.state.tickets
    ticket.pop();
    this.forceUpdate();
  },
  render: function() {
    return (
      <div>
        <IndividualTicketInput/>
        {this.state.tickets}
        <CreateTicket createTicket={this.createTicket} />
      </div>
    );
  }
});

个人票证组件

var IndividualTicketInput = React.createClass({
  getInitialState: function() {
    return { ticket: {name: '', quantity: '', price: null} };
  },
  nameChange: function(e) {
    var name = this.state.ticket.name;
    this.setState({name: e.target.value })
  },
  quantityChange: function(e) {
    var quantity = this.state.ticket.quantity;
    this.setState({quantity: e.target.value })
  },
  priceChange: function(e) {
    var price = this.state.ticket.price;
    this.setState({price: e.target.value })
  },
  deleteTicket: function(e) {
    this.setState({ ticket: [] });
  },
  render: function() {
    return (
      <ul className="individual-ticket">
        <li>
          <label>Ticket Name</label>
          <input className="ticket-name" type="text" placeholder="E.g. General Admission" onChange={this.nameChange} />
        </li>
        <li>
          <label>Quantity Available</label>
          <input className="quantity" type="number" placeholder="100" onChange={this.quantityChange} />
        </li>
          <li>
            <label>Price</label>
            <input className="price" type="number" placeholder="25.00" onChange={this.priceChange} />
          </li>
        <li>
          <RemoveTicket clickHandler={this.props.deleteTicket} />
        </li>
      </ul>
    )
  }
});

删除故障单按钮组件

var RemoveTicket = React.createClass({
  render: function() {
    return (
      <button type="button" className="delete-ticket" onClick={this.props.clickHandler}><i className="fa fa-trash-o delete-ticket"></i></button>
    );
  }
});

1 个答案:

答案 0 :(得分:2)

更新 - 2016年3月13日

首先,我会在票证数组中存储每个票证组件的状态而不是实际组件。所以Tickets组件看起来像这样:

var Tickets = React.createClass({
  getInitialState: function() {
    return {
      tickets: [{name: 'someName', quantity: '20', price: 100}],
    }
  },
  createTicket: function() {
    var tickets = this.state.tickets
    tickets.push(
      {name: '', quantity: '', price: null}
    )
    this.setState(tickets);
  },
  nameChange: function(index, e) {
    let tickets = this.state.tickets;
    tickets[index] = merge(tickets[index], { name: e.target.value })
    this.setState({tickets: tickets});
  },
  quantityChange: function(index, e) {
    let tickets = this.state.tickets;
    tickets[index] = merge(tickets[index], {quantity: e.target.value })
    this.setState({tickets: tickets});
  },
  priceChange: function(index, e) {
    let tickets = this.state.tickets;
    tickets[index] = merge(tickets[index], {price: e.target.value })
    this.setState({tickets: tickets});
  },
  deleteTicket: function(index) {
    var tickets = this.state.tickets
    tickets.splice(index, 1); 
    this.setState({tickets: tickets});
  },
  render: function() {
    console.log("tickets:", this.state.tickets);

    return (
      <div>
        {this.state.tickets.map((ticket, index) =>
           <IndividualTicketInput key={index} {...ticket} 
             deleteTicket={this.deleteTicket.bind(null, index)}
             nameChange={this.nameChange.bind(null, index)}
             quantityChange={this.quantityChange.bind(null, index)}
             priceChange={this.priceChange.bind(null, index)}
             />
        )}
        <CreateTicket createTicket={this.createTicket} /><br/><br/>
      </div>
    );
  }
});

spread属性{...ticket}将ticket的所有属性作为IndividualTicketInput组件的属性传递。 需要key={index},因此元素会获得唯一ID。

我还传递deleteTicket函数,该函数也绑定到index参数,因此它使用数组中的索引知道要删除哪个票证。稍后将其作为onClick处理程序传递给RemoveTicket按钮。

我已将nameChangepriceChangequantityChange函数移至Tickets组件,因此他们可以访问tickets数组以及其中任何一个细节发生变化,他们会在数组中更新它,而不仅仅是IndividualTicketComponent的本地状态。这样,Tickets组件具有所有子票的最新状态。

IndividualTicketInput组件不会将任何内容存储在本地状态。它使用value属性将故障单的值传递给其输入元素。当这些输入的任何值发生更改时,将调用处理程序并立即在相应的数组项中更新状态。

var IndividualTicketInput = React.createClass({
  getInitialState: function() {
    return { name: this.props.name, quantity: this.props.quantity, price: this.props.price };
  },
  render: function() {
    return (
      <ul className="individual-ticket">
        <li>
          <label>Ticket Name</label>
          <input className="ticket-name" type="text" placeholder="E.g. General Admission" onChange={this.props.nameChange} value={this.props.name} />
        </li>
        <li>
          <label>Quantity Available</label>
          <input className="quantity" type="text" placeholder="100" onChange={this.props.quantityChange} value={this.props.quantity} />
        </li>
        <li>
          <label>Price</label>
          <input className="price" type="text" placeholder="25.00" onChange={this.props.priceChange} value={this.props.price} />
        </li>
        <li>
          <RemoveTicket clickHandler={this.props.deleteTicket} />
        </li>
      </ul>
    )
  }
});

merge中处理程序中使用的Tickets函数是模块lodash的一部分。为了练习,我使用值不同于空或零的票证状态初始化数组,以查看它是否正确呈现并可以编辑,还在渲染中留下console.log以查看编辑故障单或添加新故障单时tickets数组的更改方式。

在此设置中,完成故障单编辑后,您可以将Tickets组件中的阵列发送到后端并将其保存在存储中。

我用它创建了另一个codepen以查看它的实际效果。