2016-02-26 49 views
0

我有一张桌子,其目的是为了显示来宾,并带有复选标记以指示他们是否参加。我有麻烦想办法将状态从子组件传递给父组件,同时保持它来自哪个子组件的标识。将多个子状态更改传回父级以进行保存

每一行是像下面

GuestRow = React.createClass({ 
    getInitialState() { 
    return {  
     attending: this.props.data.attending,  
     plusOneAttending: this.props.data.plusOneAttending 
    } 
    }, 

    handleCheckboxChange(field, event) { 
    if(field == 'plusOne') { 
     this.setState({ 
     plusOneAttending: event.target.checked 
     }); 
    } 
    else if (field == 'guest') { 
     this.setState({ 
     attending: event.target.checked 
     }); 
    } 
    else { 
     console.log("error third option for field"); 
    } 
    }, 

    plusOneRow() { 
    return (
     this.props.data.hasPlusOne ? 
     <input type="checkbox" 
       name="plusOneAttending" 
       defaultChecked={this.state.plusOneAttending} 
       onChange={this.handleCheckboxChange.bind(this, 'plusOne')} /> : <span>Sorry you don't have a plus one</span> 
    ) 
    }, 

    render(){ 
    return(
     <tr> 
     <td> 
      <span>{this.props.data.name}</span> 
     </td> 
     <td> 
      <input type="checkbox" 
       name="attending" 
       defaultChecked={this.state.attending} 
       onChange={this.handleCheckboxChange.bind(this, 'guest')} /> 
     </td> 
     <td> 
      {this.plusOneRow()} 
     </td> 
     </tr> 
    ); 
    } 
}); 

这些被渲染到父表容器,其是

RsvpForm = React.createClass({ 
    getInitialState() { 
    return { 
     guests: this.props.data.guests 
    } 
    }, 

    saveChanges(event) { 
    event.preventDefault(); 

    //console.log(test); 
    }, 

    render() { 
    var guestRows = this.state.guests.map(function(guest){ 
     return (
     <GuestRow callBackToParent={this.onChildChange} data={guest} /> 
    ) 

    }, this); 

    return (
     <div id="rsvp"> 
     <span>Welcome {this.props.data.invitationName}! Thank you for taking part in our wedding!</span> 
     <br /> 
     <table> 
      <thead> 
      <tr> 
       <th>Guest</th> 
       <th>Are you attending?</th> 
       <th>Plus one?</th> 
      </tr> 
      </thead> 
      {guestRows} 
     </table> 
     <br /> 
     <button onClick={this.saveChanges}>Save!</button> 
     </div> 
    ) 
    } 
}); 

guests对象看起来像以下的成分。该示例只有一个访客,但它可以是一个有唯一PID的有效访客数组。

guests: [ 
     { 
      pid: new Meteor.Collection.ObjectID(), 
      name: "Joe Somebody", 
      attending: true, 
      hasPlusOne: true, 
      plusOneAttending: false 
     } 

我想过加入个人guest记录的状态到母部件,但它怎么会何时guests比2+记录更大的工作。我是否动态添加更多状态项目?或者我应该使用ref从子组件中提取数据。但是,如何唯一标识每一个,并确保我正在更新MongoDb上的正确记录?

回答

1

以下是您可以使用的示例代码示例。我所做的是基本的,但也不是100%干净,我个人可能会略微不同。我还可以建议你考虑一下Flux之类的东西。

无论如何,这里是我的伪代码。所以我所做的基本上是最高级的状态,让下面的组件只担心它的道具。这通常是一种很好的模式,您可以根据道具轻松定义行为,并让上述组件(状态更改后)为其提供新值。

Form = React.createClass({ 
    onGuestChange(id, guest){ 
     //set state with new guests etc 
    } 

    render() { 
     var guestRows = this.state.guests.map(function(guest) { 
      return (
       <Guestrow onGuestChange={this.handleGuestChange} data={guest}></Guestrow? 
      ); 
     }) 
     return() { 
      <div>{guestRows}</div> 
     } 
    } 
}); 

GuestRow = React.createClass({ 
    handleAttendingChange(id, event){ 
     var guest = this.props.data 
     guest.attending = event.target.checked; 
     this.props.onGuestChange(id, guest); 
    } 

    render() { 
     return(
      <div><input type='checkbox' name='attending' checked={this.props.data.attending} onChange={this.handleAttendingChange.bind(this, this.props.data.id)}></input></div> 
     ); 
    } 
}); 
+0

更多地考虑到这个问题,Flux具有很大的意义。但我喜欢你如何使用绑定来将'(id,event)'一起传递,以保持更改正确分配。 – tyh

+0

我也会使用与Flux的绑定,这是一个非常方便的模式,可以让事情更加分离。 –

0

在你的父母,做一个功能改变的状态

// parent component 
addMoreGuest(guest) { 
    var guests = _.clone(this.state('guests')); 
    guests.push(guest); 

    this.setState({guests: guests}); 
} 

,然后,通过addMoreGuest作为回调像你onChildChange

<Child callback={this.addMoreGuest} /> 

在孩子一样,做一个包装回拨

triggerCallback(guest) { 
    this.props['callback'](guest); 
} 

通过这种方式,您可以发送da ta从孩子到父母,然后更新父母的状态。阅读更多关于此的here