【问题标题】:ReactJS with Material-UI: How to sort an array of Material-UI's <TableRow> alphabetically?ReactJS with Material-UI:如何按字母顺序对 Material-UI 的 <TableRow> 数组进行排序?
【发布时间】:2017-03-25 07:32:09
【问题描述】:

目前,我使用&lt;TableRow&gt;s 的数组并使用.map() 渲染Material-UI 的&lt;Table&gt;'s &lt;TableRow&gt; (http://www.material-ui.com/#/components/table)。每个&lt;TableRow&gt; 都有一个代表名字的&lt;TableRowColumn&gt;,例如&lt;TableRowColumn&gt;Josh&lt;/TableRowColumn&gt;

但是,如果用户按下按钮,我想按 &lt;TableRowColumn&gt;'s 名字的字母顺序对 &lt;TableRow&gt; 数组进行排序。比如说,在 10 个 &lt;TableRow&gt;s 中,如果数组 [0] 有名字 Conny,数组 [1] 有 Adrian,那么希望数组 [1] 变成数组 [0]。

正确的方法是什么?任何指导或见解将不胜感激。

编辑

每一行都将使用数组rows 呈现,该数组具有属性firstNamefavColor 的对象:

        {
          rows.map((row) => {
            return(
              <UserRow
                firstName={row.firstName}
                favColor={row.favColor}
              />
            )
          })
        }

每一行的定义如下:

const UserRow = (props) => {
  const {firstName, favColor} = props

  return (
    <TableRow>
      <TableRowColumn>{firstName}</TableRowColumn>
      <TableRowColumn>{favColor}</TableRowColumn>
    </TableRow>
  )
}

【问题讨论】:

    标签: javascript arrays reactjs react-jsx material-ui


    【解决方案1】:

    我会在应用将创建TableRowsmap 操作之前对数组进行排序。

    react 的思维方式是声明式的。这意味着在视觉层面上,您应该提供应该显示的元素。因此,它们在传递给视图组件之前被排序。

    例如(我不能使用 material-ui 元素,因为该示例没有在 stackoverflow 设置中运行。只需将 TableComponent 的所有元素替换为它们的 material-ui 改变自我。):

    const data = [
      {firstname: "John", lastname: "Rover",  id:12},
      {firstname: "Bob",  lastname: "Taylor", id:24},
      {firstname: "Lucy", lastname: "Heart",  id:43}
    ]
    
    // The table component is unaware of the data order operations
    const TableComponent = ({tableData}) => <table><tbody>
      {tableData.map(d=> <tr key={d.id}>
          <td>{d.firstname}</td>
          <td>{d.lastname}</td>
      </tr>)}
    </tbody></table>
    
    // The parent component takes care of feeding the Table
    // component with the data in the correct order.  
    class App extends React.Component {
      state = { sortBy: "firstname"}
      handleChange = (event) => this.setState(
        {sortBy: event.target.value}
      );
      render () {
        const {data} = this.props; 
        const {sortBy} = this.state;
        const sortedData = data.sort((a,b) => a[sortBy]>b[sortBy]?1:-1)
        return <div>
          Sort by  
          <select value={sortBy} onChange={this.handleChange}>
            <option value="firstname">First Name</option>
            <option value="lastname">Last Name</option>
          </select>
          <h2>The table: </h2>
          <TableComponent tableData={sortedData} />
        </div>
      }
    }
      
    ReactDOM.render(
      <App data={data} />,
      document.getElementById('root')
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    <div id="root"></div>

    【讨论】:

    • 你介意解释一下a.firstname&gt;b.firstname?-1:1 在做什么,我如何让它适用于不同数量的行?
    • 我已经编辑了我的答案。这只是我用来对表数据数组进行排序的比较函数。要将其扩展到各种数量的原始数据,您需要使用布尔值以外的其他值来定义要排序的列。
    • 我已经更新了我的示例以使用选择而不是单选按钮。我希望它有所帮助。
    • 我尝试了一下,但没有使用我所拥有的。请看一下原帖。我已经用我的代码更新了它。在这种情况下,如何在按下按钮时按属性firstName 的字母顺序对数组rows 进行排序,以便使用排序后的数组重新呈现行?
    • react 的方式是在映射到 DOM 元素之前对数组进行排序。因此,为什么我不建议对材料 Ui 行进行排序。
    【解决方案2】:

    这是一个完整的应用示例,其中包含一个表格,可以通过单击标题对其行进行排序。评论是内联和the full example is available here

    表格的状态包含每次单击表格列标题时排序的行以及排序列的属性名称。

    import React from 'react';
    import { MuiThemeProvider} from 'material-ui';
    import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui';
    
    // properties of TableHeader component
    let headerProps = {
      enableSelectAll: false,
      displaySelectAll: false,
      adjustForCheckbox: false
    };
    
    // initial set of rows, simulating data from the database
    let rows = [
      {firstName: "Adrian", favColor: "gold", uniqueId: 0 },
      {firstName: "Alma", favColor: "green", uniqueId: 1 },
      {firstName: "Conny", favColor: "black", uniqueId: 2 },
      {firstName: "Jane", favColor: "blue", uniqueId: 3 }
    ];
    
    // our table hader information, key is the name of the 
    // property to sort by when the header is clicked 
    let headers = [
      {name: "First Name", key: "firstName"},
      {name: "Favorite Color", key: "favColor"}
    ];
    
    
    // our table component that can sort columns
    class SortableTable extends React.Component {
      
      constructor(props){
        super(props);
        this.state = {rows, sortBy: 'firstName'};
      }
    
      renderHeaders(){
        let header= headers.map( (h) => {
          return <SortableHeader 
                    key={h.key}
                    name={h.name}
                    onClicked={()=>this.updateSortBy(h.key)} 
                    isSortColumn={this.state.sortBy == h.key}/>
        });
        return <TableRow>{header}</TableRow>;
      }
      
      renderRows() {
        return this.state.rows.map( (row, i) => <UserRow {...row} key={row.uniqueId}/> );
      }
                                   
      updateSortBy(sortBy){
          // multiple clicks on the same column reverse the sort order
          if( sortBy == this.state.sortBy ){
            this.setState( {rows: [...this.state.rows.reverse()]} );
            return;
          }
          
          let rows = [...this.state.rows];
          rows.sort( (a,b) => {
            if (a[sortBy] < b[sortBy])
              return -1;
            if(a[sortBy] > b[sortBy])
              return 1;
            return 0;
          });
          
          this.setState({rows, sortBy});
        }
    
          
      render() {
        return (
            <MuiThemeProvider>
            <Table>
              <TableHeader {...headerProps}>
                  {this.renderHeaders()}
              </TableHeader>
              <TableBody>
                {this.renderRows()}
              </TableBody>
            </Table>
          </MuiThemeProvider>
        );
      }
    }
    
      
      
    function SortableHeader(props){
      let style = {
        cursor: "pointer"
      }
      if(props.isSortColumn){
        style.fontWeight = "bold";
        style.color = "black";
      }
      
      return (
        <TableHeaderColumn>
          <div style={style} onClick={() => props.onClicked()}>{props.name}</div>
        </TableHeaderColumn>
      );
    }
      
    
    function UserRow(props){
      return (
        <TableRow>
          <TableRowColumn>{props.firstName}</TableRowColumn>
          <TableRowColumn>{props.favColor}</TableRowColumn>
        </TableRow>
      );
    }
    
    export default SortableTable;

    【讨论】:

      猜你喜欢
      • 2017-04-07
      • 2013-04-07
      • 2017-02-07
      • 2017-06-02
      • 1970-01-01
      • 2015-05-17
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      相关资源
      最近更新 更多