ReactJS with Material-UI:如何按字母顺序对 Material-UI 的 <TableRow> 数组进行排序?

Posted

技术标签:

【中文标题】ReactJS with Material-UI:如何按字母顺序对 Material-UI 的 <TableRow> 数组进行排序?【英文标题】:ReactJS with Material-UI: How to sort an array of Material-UI's <TableRow> alphabetically? 【发布时间】: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>
  )

【问题讨论】:

【参考方案1】:

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

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

例如(我不能使用 material-ui 元素,因为该示例没有在 *** 设置中运行。只需将 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;

【讨论】:

以上是关于ReactJS with Material-UI:如何按字母顺序对 Material-UI 的 <TableRow> 数组进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS + Material-UI:如何使用 Material-UI 的 <DatePicker> 将当前日期设置为默认值?

ReactJS + Material-UI:如何在每个 TableRow 中使用 Material-UI 的 FlatButton 和 Dialog?

ReactJS + Material-UI:如何在 Material-UI <Table/> 的 <TableRow/> 之间交替颜色?

如何在 Material-UI、ReactJS 中从分页中设置分页项的样式?

ReactJS material-ui TextField 应用 css

使用带有 reactjs 和 redux 的 Material-ui 复选框