2017-12-08 4 views
-1

APIからフェッチされたデータをテーブルに出力しています。カラム値をアルファベット順および数値順に並べ替えるのが困難です。 API内の列のデータが数値で構成されている場合、すなわち10.01, 333.01, 8.99 or 100.88など100 -> 0を降順最初のクリックにし、2回目のクリックで0 -> 100から昇順でソートし、アルファベット順の値に対して同じロジック、つまりINにa-z && Z-Aおよびその逆。私はJavaScriptでそれを符号化するために使用されるように私はonclick="sortTable(0)"に精通していますReactJS:動的にレンダリングされたonClick()ソート要素

機能は、リアクトで同じように機能しません。おそらく、私はES6の標準を誤解していますが、わかりません。ここで

Here is how it's look like my table without sorting functionality.

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)"が使用された直後には、coのエラーは発生しませんnsoleと同じ結果を出力します。私は正しいとは思わない<th onClick={this.handleClick}>{column}</th>要素です。

onClick event doesn't dunction

残念ながら、私は、私はどちらかSORの機能をデバッグすることができないように、それは、全くonClickイベントを機能していないです​​

に関連するドキュメントを見つけることができませんでした。

ご了承ください。

答えて

0

onClick =()=> this.sortable(0)。そのような場合にループを使用している場合は、別の関数にインデックスを渡して、正しいindexの値を渡す必要があります。説明 React OnClick for item not working

+0

こんにちは@ stack26回答ありがとうございますが、これは私のケースに関連しているとは思わないです。最初に、ここでは列と行を別々に配列しています。上記の説明では、列のヘッダー要素を使ってonClickイベントを通じて行の値の並べ替えを処理したいと述べています。 – antdimit

0

あなたのコードが実際にsortTableメソッドを呼び出すところ、私が表示されていないため、このリンクを参照してください、私はここに大きな問題があると考えています。

非常に良い理由がない限り、手動でDOM操作を行うべきではありません。代わりに、Reactに依存してDOMを操作してください。なぜそれを使用しているのですか?内部のstateとそのpropsに基づいてコンポーネントの表示を記述する責任は、render()の機能に反映する必要があります。あなたの場合、行の順序は、現在の並べ替えの列と並べ替えの方向によって異なります。したがって、並べ替えのcolumnとソートのdirectionを含むオブジェクトである可能性がありますsortの追加の状態を追加することができます。列がクリックされるたびに、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> 
); 
} 

はまた、ReactDOM.render()コールは、あなたが提供リアクト要素とDOM要素の内容を置き換えます。アプリコンテナとして<div id="root">を使用して、そのコンテンツをアプリに置き換えるのが一般的な方法です。

ReactDOM.render(<App />, document.getElementById("root")); 
+0

フィードバックをお寄せいただきありがとうございますが、あなたの提案は機能しません。** renderHeader **はどこにも定義していないからです。 ' '要素の間に本文をレンダリングしなければならないので、レンダリングはあなたのステートメントでは機能しません。そうでない場合は何も印刷せず、' root'の代わりに 'id'が' container'です。 'ReactDOM.render(

、document.querySelector( 'body')); ' – antdimit

+0

これはコピーして貼り付けるつもりはありませんでした。 'getSortFunction'と' renderHeader'関数をどのように実装すればよいか分からなければ、あなたが何らかの努力をした後にあなたを導く助けとなります。また、 'render()'のjsxをあなたのニーズに合わせて変更することができます。私は例を提供しています。 –

関連する問題