2016-12-15 56 views
0

我有一个表格,它有一个设置图标作为最后一列,每当用户点击它时,它应该弹出打开设置菜单。要在活动类之间切换,我使用了state并将其传递给array.map函数,但是发生的情况是,每当用户单击一个设置图标时,所有菜单都会同时打开,原因是它们都具有相同的单击事件和相同的状态变量。如何将其更改为只有点击的设置图标应打开其菜单的位置?我的代码如下。React JS将单独的onclick事件分配给表格的每一行

import React, { Component, PropTypes } from 'react'; 
import '../../../assets/custom_css/tables/unstackable_very_basic_striped_users_table.css'; 
import { v4 } from 'node-uuid'; 
import Language from '../../../assets/language'; 

class UnstackableVeryBasicStripedUsersTable extends Component { 

    static propTypes = { 
     rows: PropTypes.array.isRequired 
    }; 

    constructor(props) { 
     super(props); 
     this.getTableRows = this.getTableRows.bind(this); 
     this.open_setting_menu = this.open_setting_menu.bind(this); 
     this.state = { 
      is_action_menu_active: false 
     }; 
    } 

    getTableRows() { 
     const { rows } = this.props; 
     return rows.map(row => { 
      let drop_down_class = (this.state.is_action_menu_active) ? "active" : ""; 
      let menu_class = (this.state.is_action_menu_active) ? "transition visible" : ""; 
      return <tr key={v4()}> 
       {row.map(info => { 
        return <td key={v4()}> 
         {info} 
        </td> 
       })} 
       <td> 
        <div className={"ui right pointing dropdown icon " + drop_down_class} onClick={this.open_setting_menu}> 
         <i className="setting icon"/> 
         <div className={"menu " + menu_class}> 
          <div className="item">Edit</div> 
          <div className="item">Delete</div> 
         </div> 
        </div> 
       </td> 
      </tr> 
     }); 
    } 

    open_setting_menu() { 
     this.setState({ 
      is_action_menu_active: !this.state.is_action_menu_active 
     }); 
    } 

    render() { 
     return <table className="ui unstackable celled very basic striped table unstackable_very_basic_striped_table"> 
      <thead> 
       <tr> 
        <th>{Language.name}</th> 
        <th>{Language.role}</th> 
        <th>{Language.department}</th> 
        <th>{Language.action}</th> 
       </tr> 
      </thead> 
      <tbody> 
       {this.getTableRows()} 
      </tbody> 
     </table> 
    } 
} 

export default UnstackableVeryBasicStripedUsersTable; 
+0

不'row'有一个独特的ID? –

+0

也许您可以存储要显示菜单的行的ID。 – DLight

回答

2

如果你想使用一个单一的组件,可以保存选定行的索引的状态:

import React, { Component, PropTypes } from 'react'; 
import '../../../assets/custom_css/tables/unstackable_very_basic_striped_users_table.css'; 
import { v4 } from 'node-uuid'; 
import Language from '../../../assets/language'; 

    class UnstackableVeryBasicStripedUsersTable extends Component { 

     static propTypes = { 
      rows: PropTypes.array.isRequired 
     }; 

     constructor(props) { 
      super(props); 
      this.getTableRows = this.getTableRows.bind(this); 
      this.open_setting_menu = this.open_setting_menu.bind(this); 
      this.state = { 
       selected_row_index: 0, 
       is_action_menu_active: false 
      }; 
     } 

     getTableRows() { 
      const { rows } = this.props; 
      return rows.map((row, index) => { 
       let drop_down_class = (this.state.is_action_menu_active && this.state.selected_row_index === index) ? "active" : ""; 
       let menu_class = (this.state.is_action_menu_active && this.state.selected_row_index === index) ? "transition visible" : ""; 
       return <tr key={v4()}> 
        {row.map(info => { 
         return <td key={v4()}> 
          {info} 
         </td> 
        })} 
        <td> 
         <div className={"ui right pointing dropdown icon " + drop_down_class} onClick={() => this.open_setting_menu(index)}> 
          <i className="setting icon"/> 
          <div className={"menu " + menu_class}> 
           <div className="item">Edit</div> 
           <div className="item">Delete</div> 
          </div> 
         </div> 
        </td> 
       </tr> 
      }); 
     } 

     open_setting_menu(index) { 
      this.setState({ 
       is_action_menu_active: !this.state.is_action_menu_active, 
       selected_row_index: index 
      }); 
     } 

     render() { 
      return <table className="ui unstackable celled very basic striped table unstackable_very_basic_striped_table"> 
       <thead> 
        <tr> 
         <th>{Language.name}</th> 
         <th>{Language.role}</th> 
         <th>{Language.department}</th> 
         <th>{Language.action}</th> 
        </tr> 
       </thead> 
       <tbody> 
        {this.getTableRows()} 
       </tbody> 
      </table> 
     } 
    } 

    export default UnstackableVeryBasicStripedUsersTable; 
+1

差不多,但这会在渲染时调用函数,而不是点击 –

+0

@DavinTryon很好的捕捉!我编辑了我的答案,并添加了一个箭头函数,以避免调用onclick渲染 –

+1

@DavinTryon如果你不想使用箭头函数,也可以尝试在事件处理函数中绑定函数,而不是构造函数this.open_setting_menu.bind( this,index)'(它的性能稍差一些,因为每次组件重新呈现时函数都是有界的) –