【问题标题】:Loading more rows after click event in Sortable Table Material UI table and React在 Sortable Table Material UI 表和 React 中单击事件后加载更多行
【发布时间】:2018-03-01 14:54:59
【问题描述】:

我正在使用 Material UI 和 React 制作一个可排序的表格组件。 我要实现的功能是

  • 4 行可排序表
  • 当用户单击“加载更多”时,默认数据下方将多显示 4 行。

目前,我在第一个之后添加了另一个 renderRows()。它在一个表中显示 8 行。但是数据是按每个renderRows() 排序的。

图片 1 默认页面

图2点击事件后

代码

// properties of TableHeader component
let headerProps = {
enableSelectAll: false,
displaySelectAll: false,
adjustForCheckbox: false
};

 // initial set of rows, simulating data from the database
 let rows = [
 {date: "12:30 12.9.2017", payment: "MasterCard", narrative: "restige 
Cosmetics, Total Intensity Eyeliner Long Lasting Intense Color, Deepest 
Black, 1.2 g (.04 oz)", amount: "$912.51", uniqueId: 0 },
{date: "11:30 12.9.2017", payment: "Visa", narrative: "Total Intensity 
Eyeliner Long Lasting Intense Color, Deepest Black, 1.2 g (.04 oz)", 
amount: "$744.51", uniqueId: 1 },
{date: "13:30 12.9.2017", payment: "PayPal", narrative: "Eyeliner Long 
Lasting Intense Color, Deepest Black, 1.2 g (.04 oz)", amount: "$12.51", 
uniqueId: 2 },
{date: "20:30 12.9.2017", payment: "MasterCard", narrative: "Long 
Lasting Intense Color, Deepest Black, 1.2 g (.04 oz)", amount: "$16.51", 
uniqueId: 3 }
 ];

// our table hader information, key is the name of the 
// property to sort by when the header is clicked 
let headers = [
{name: "", key: "checkbox"},
{name: "Today", key: "date"},
{name: "Payment", key: "payment"},
{name: "Narrative", key: "narrative"},
{name: "Amount", key: "amount"}
 ];

 // our table component that can sort columns
 class SortableTable extends React.Component {

 constructor(props){
 super(props);
 this.state = {rows, 
              sortBy: 'firstName',
              tableOpen : false
            };
  }

 handleClick = (event) => {
 event.preventDefault();
 this.setState({
  tableOpen : !this.state.tableOpen
 })
}

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 (
  <div>
    <MuiThemeProvider>
    <Table>
      <TableHeader {...headerProps}>
          {this.renderHeaders()}
      </TableHeader>
      <TableBody>
        {this.renderRows()}
        {!this.state.tableOpen ? this.renderRows() : "" }
      </TableBody>
    </Table>   
  </MuiThemeProvider>
  <p className="openTable" onClick={this.handleClick} >LOAD MORE</p>
  </div>
  );
 }
}



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}
  {props.name==""? "" :<img src={arrowUpDown} alt="arrowUpDown" 
  className="arrowUpDown"/>}</div>
  </TableHeaderColumn>
  );
 }


 function UserRow(props){
 return (
 <TableRow>
  <TableRowColumn><img src={Check} alt="Check" className="Check"/>
 </TableRowColumn>
  <TableRowColumn>{props.date}</TableRowColumn>
  <TableRowColumn>{props.payment=="Visa" ?  <img src={Visa} alt="Visa" 
  className="Visa"/> :  (props.payment=="PayPal" ?  <img src={Paypal} 
  alt="Paypal" className="Master"/> :  <img src={Master} alt="Master" 
  className="Master"/>)}


  {props.payment}</TableRowColumn>
   <TableRowColumn>{props.narrative}</TableRowColumn>
   <TableRowColumn>{props.amount}</TableRowColumn>
   </TableRow>
 );
 }

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    updateSortBy() 方法只对当前在this.state.rows 中的内容进行排序,因此调用renderRows() 两次只会依次呈现排序后的集合。

    您可能希望 LOAD MORE 点击事件向状态添加更多行,这样排序和渲染方法将作用于完整的数据集,而不是数据的两个实例。

    这样的……

    // properties of TableHeader component
    let headerProps = {
        enableSelectAll: false,
        displaySelectAll: false,
        adjustForCheckbox: false
    };
    
    // initial set of rows, simulating data from the database
    let rows = [
        {
            date: "12:30 12.9.2017",
            payment: "MasterCard",
            narrative: "restige Cosmetics, Total Intensity Eyeliner Long Lasting Intense Color, Deepest Black, 1.2 g (.04 oz)",
            amount: "$912.51",
            uniqueId: 0
        },
        {
            date: "11:30 12.9.2017",
            payment: "Visa",
            narrative: "Total Intensity Eyeliner Long Lasting Intense Color, Deepest Black, 1.2 g (.04 oz)",
            amount: "$744.51",
            uniqueId: 1
        },
        {
            date: "13:30 12.9.2017",
            payment: "PayPal",
            narrative: "Eyeliner Long Lasting Intense Color, Deepest Black, 1.2 g (.04 oz)",
            amount: "$12.51",
            uniqueId: 2
        },
        {
            date: "20:30 12.9.2017",
            payment: "MasterCard",
            narrative: "Long Lasting Intense Color, Deepest Black, 1.2 g (.04 oz)",
            amount: "$16.51",
            uniqueId: 3
        }
    ];
    
    // our table hader information, key is the name of the 
    // property to sort by when the header is clicked 
    let headers = [
        { name: "", key: "checkbox" },
        { name: "Today", key: "date" },
        { name: "Payment", key: "payment" },
        { name: "Narrative", key: "narrative" },
        { name: "Amount", key: "amount" }
    ];
    
    // our table component that can sort columns
    class SortableTable extends React.Component {
    
        constructor(props) {
            super(props);
            this.state = {
                rows,
                sortBy: 'firstName',
                tableOpen: false
            };
        }
    
        handleClick = (event) => {
            event.preventDefault();
    
            // create a new array containing the old and new rows
            const newRows = [...this.state.rows, ...rows];
    
            this.setState({
                tableOpen: !this.state.tableOpen,
                rows: newRows // update the state with the new rows
            })
        }
    
        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 (
                <div>
                    <MuiThemeProvider>
                        <Table>
                            <TableHeader {...headerProps}>
                                {this.renderHeaders()}
                            </TableHeader>
                            <TableBody>
                                {this.renderRows()}
                                {/*no need to call this.renderRows() twice*/}
                                {/*{!this.state.tableOpen ? this.renderRows() : ""}*/}
                            </TableBody>
                        </Table>
                    </MuiThemeProvider>
                    <p className="openTable" onClick={this.handleClick} >LOAD MORE</p>
                </div>
            );
        }
    }
    
    
    
    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}
                    {props.name == "" ? "" : <img src={arrowUpDown} alt="arrowUpDown"
                        className="arrowUpDown" />}</div>
            </TableHeaderColumn>
        );
    }
    
    
    function UserRow(props) {
        return (
            <TableRow>
                <TableRowColumn><img src={Check} alt="Check" className="Check" />
                </TableRowColumn>
                <TableRowColumn>{props.date}</TableRowColumn>
                <TableRowColumn>
                    {
                        props.payment == "Visa" ?
                            <img src={Visa} alt="Visa" className="Visa" /> :
                            (
                                props.payment == "PayPal" ?
                                    <img src={Paypal} alt="Paypal" className="Master" /> :
                                    <img src={Master} alt="Master" className="Master" />
                            )
                    }
    
                    {props.payment}
                </TableRowColumn>
                <TableRowColumn>{props.narrative}</TableRowColumn>
                <TableRowColumn>{props.amount}</TableRowColumn>
            </TableRow>
        );
    }

    【讨论】:

    • 我添加了您的解决方案,但我的控制台出现错误。 '' flattenChildren(...):遇到两个孩子用同一个key,.$3。子键必须是唯一的;当两个孩子共享一个密钥时,只会使用第一个孩子。”我添加了另一个ID不同的数据集调用rows2。然后它起作用了。谢谢你指导我正确的方式。
    • 您看到的错误可能来自renderRows() 方法,因为您使用row.uniqueId 值作为组件的键。这是一种很好的做法,但是由于您要复制数据集,因此您将重复使用唯一 ID。实际上,此数据将来自所有 ID 都是唯一的外部数据源,您将避免此错误。
    猜你喜欢
    • 2019-10-18
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    相关资源
    最近更新 更多