2015-12-23 118 views
7

什麼是處理深層節點中狀態更改的最佳方式,這也需要由父節點處理。這裏是我的情況:React事件層次結構問題

<Table> 
 
    <Row prop={user1}> 
 
    <Column prop={user1_col1} /> 
 
    <Column prop={user1_col2} /> 
 
    </Row> 
 
    <Row prop={user2}> 
 
    <Column prop={user2_col1} /> 
 
    <Column prop={user2_col2} /> 
 
    </Row> 
 
    <TableFooter> 
 
    <FooterColumn prop={sum1} /> 
 
    <FooterColumn prop={sum2} /> 
 
    </TableFooter> 
 
</Table>

每當有人正在改變在列屬性什麼,我只需要該列組件內保持這個值的狀態。但是,我現在想在FooterColumn組件中使用這些值的總和。達到此目的的最佳方法是什麼?

如果我要拋棄狀態改變,我必須在多個地方保持狀態,然後將其傳遞下去,這是一項繁瑣的工作。最好是使用EventEmitters還是我錯過了一些東西?

回答

5

因此,所有你需要的是跟蹤國家在父組件和共享狀態更新功能,與孩子們:

var Parent = React.createClass({ 
    getInitialState: function() { 
    return { 
     users: [ 
     {name: 'Matt', values: [1, 2]}, 
     {name: 'user517153', values: [4, 5]} 
     ] 
    }; 
    }, 
    updateValue: function(rowId, colId, newValue) { 
    var newUsersState = this.state; 
    newUsersState.users[rowId].values[colId] = newValue; 
    this.setState({users: newUsersState}); 
    }, 
    render: function() { 
    var rows = this.state.users.map(function(user, r) { 
     var cols = user.values.map(function(value, c) { 
     return (
      <Column key={c} prop={value} rowId={r} colId={c} onChange={this.updateValue}/> 
     ); 
     }); 

     return (
     <Row key={r} prop={user}> 
      {cols} 
     </Row> 
    ); 
    }); 

    // Yes, it could be more efficient if you did it all in one map/forEach - doing this in a second one for clarity 
    var footerCols = this.state.users.map(function(user) { 
     var sum = 0; 
     user.values.forEach(function(value) { sum+= value; }); 
     return (
     <FooterColumn prop={sum} /> 
    ); 
    }); 

    return (
     <Table> 
     {rows} 
     <TableFooter> 
      {footerCols} 
     </TableFooter> 
     </Table> 
    ); 
    } 
}); 

在你Column類,你只需要沿着線的東西作者:

var Column = React.createClass({ 
    onChange: function(event) { 
    var props = this.props; 

    var newValue = event.target.value; // Get the new value somehow - this is just an example 
    props.onChange(props.rowId, props.coldId, newValue); 
    }, 
    render: function() { 
    var props = this.props; 

    return (
     <td onChange={this.onChnage}>{props.prop}</td> 
    ); 
    } 
}); 

希望是有道理的。

+0

我第二個這個。您應該努力將所有應用程序邏輯保留在最上面的組件中,並讓嵌套組件只在其內發生某些事件時呈現其屬性和觸發事件,以便父級可以使用回調來響應這些更改。 – juandemarco

+0

謝謝!但事情是,我也有一個Row組件,這意味着將它傳遞給2次。如果我應該創建另一個子組件,它將是3次,這些看起來非常乏味。這是你應該已經使用Flux之類的地方嗎? – user517153

+0

所以,首先,上面使用的「Row」實際上並不是「Column」的父項,因此「Row」不需要知道任何關於Column的道具。在React中,如果組件直接呈現子組件,則該組件是另一個組件的父組件。因此,您可以使用一個名爲'DivMaker'的組件,其中包含100個嵌套div,但所有這些div的父組件都是'DivMaker',無論它們的嵌套深度如何。 –