我正在将从API获取的数据打印到表中,我在按字母顺序和数字顺序对列值进行排序时遇到一些困难。如果API中的列数据包含数值,即 10.01, 333.01, 8.99 or 100.88
等,则可以在首次点击时从 0 -> 100
进行升序排序第二次点击降序 100 -> 0
,并按字母顺序排列相同的逻辑,即 a-z && Z-A
,反之亦然。
我熟悉的功能 onclick="sortTable(0)"
,在React中的功能不一样,就像我以前用javaScript编写代码一样。可能我误导了ES6标准,但我不确定。
以下是我的代码示例 onclick="sortTable(0)"
,但它不能很好地运作:
class App extends React.Component
{
constructor()
{
super();
this.state = {
rows: [],
columns: [],
clicked: false
}
this.handleClick = this.handleClick.bind( this );
}
handleClick()
{
this.setState( {
clicked: true
} );
}
sortTable( n )
{
var table, columns, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById( "datagrid" );
switching = true;
//Set the sorting direction to ascending:
dir = "asc";
/*Make a loop that will continue until
no switching has been done:*/
while ( switching )
{
//start by saying: no switching is done:
switching = false;
columns = table.getElementsByTagName( "TH" );
/*Loop through all table rows (except the
first, which contains table headers):*/
for ( i = 1; i < ( columns.length - 1 ); i++ )
{
//start by saying there should be no switching:
shouldSwitch = false;
/*Get the two elements you want to compare,
one from current row and one from the next:*/
x = columns[i].getElementsByTagName( "TH" )[n];
y = columns[i + 1].getElementsByTagName( "TH" )[n];
/*check if the two rows should switch place,
based on the direction, asc or desc:*/
if ( dir == "asc" )
{
if ( x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase() )
{
//if so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
} else if ( dir == "desc" )
{
if ( x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase() )
{
//if so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
}
}
if ( shouldSwitch )
{
/*If a switch has been marked, make the switch
and mark that a switch has been done:*/
rows[i].parentNode.insertBefore( rows[i + 1], rows[i] );
switching = true;
//Each time a switch is done, increase this count by 1:
switchcount++;
} else
{
/*If no switching has been done AND the direction is "asc",
set the direction to "desc" and run the while loop again.*/
if ( switchcount == 0 && dir == "asc" )
{
dir = "desc";
switching = true;
}
}
}
}
componentDidMount()
{
fetch( "http://ickata.net/sag/api/staff/bonuses/" )
.then( function ( response )
{
return response.json();
} )
.then( data =>
{
this.setState( { rows: data.rows, columns: data.columns } );
} );
}
render()
{
return (
<div id="container" className="container">
<h1>Final Table with React JS</h1>
<table className="datagrid">
<thead>
<tr> {
this.state.columns.map(( column, index ) =>
{
return ( <th onClick={this.handleClick}>{column}</th> )
}
)
}
</tr>
</thead>
<tbody> {
this.state.rows.map( row => (
<tr>{row.map( cell => (
<td>{typeof cell === 'number' ? cell.toFixed( 2 ) : cell}</td>
) )}
</tr>
) )
}
</tbody>
</table>
</div>
)
}
}
ReactDOM.render( <div id="container"><App /></div>, document.querySelector( 'body' ) );
欢迎您直接参与我的回购:Fetching API data into a table
我的示例,在使用 onclick="sortTable(0)"
之后,并未在控制台中显示任何错误,但它会打印相同的结果。我想我没有正确处理 <th onClick={this.handleClick}>{column}</th>
元素。
很遗憾,我无法在ReactJs.org
找到相关文档根本没有onClick事件的功能,因此我无法调试sor功能。
任何建议将不胜感激!
答案 0 :(得分:0)
onClick =()=&gt; this.sortable(0)。如果在这种情况下使用任何类型的循环,则必须将索引传递给另一个函数以传递正确的索引值。请参阅此链接以获取解释 React OnClick for item not working
答案 1 :(得分:0)
我没有看到您的代码实际调用sortTable
方法的位置,但我相信这里有一个更大的问题。
除非你有充分的理由,否则你不应该手动进行DOM操作。相反,依靠React操纵DOM,这就是你使用它的原因。您有责任根据内部state
及其props
来描述组件的显示,这是render()
功能应该反映的内容。在您的情况下,行的顺序将取决于当前排序列和排序方向。因此,您可以为sort
添加其他状态,该状态可能是包含column
排序和direction
排序的对象。每当单击一列时,您都会更新sort
,这将导致您的组件重新渲染。然后,您的render()
函数会在显示行时考虑当前的sort
状态。
因此,要渲染行,您可以写:
renderRows() {
const sortFn = getSortFunction(this.state.sort); // defined elsewhere
// shallow copy so we don't mutate the state
return [ ...this.state.rows ]
.sort(sortFn)
.map((row, i) => (
<tr key={i}>
{ row.map((cell, j) => <td key={j}>{ cell }</td>) }
</tr>
));
}
render() {
return (
<table>
<thead>{ renderHeader() }</thead>
<tbody>{ renderRows() }</tbody>
</table>
);
}
此外,在呈现React应用程序时,ReactDOM.render()
调用会使用您提供的React元素替换DOM元素的内容。通常的做法是将<div id="root">
用作应用容器,然后将其内容替换为您的应用。
ReactDOM.render(<App />, document.getElementById("root"));