2015-12-17 16 views
6

私はリアクションの概念、特に小さな状態のスポーツの名簿のようなUIを記述して、状態と動的なUIを学ぼうとしています。私は以下のコードを含んでおり、アプリ全体+画像はhttp://codepen.io/emkk/pen/dGYXJOです。このアプリは基本的に私が前に定義したプレーヤーオブジェクトの配列からプレーヤーカードを作成します。React.js - コンポーネントのソートの実装

私はボタンをクリックするとプレーヤーカードのソートを実装したいと思います。私は上記のボタンを描画する<Sort/>コンポーネントを作成しました。イベントリスナーを添付しますが、それを私の<Roster/>コンポーネントに反映させる方法はわかりません。私はthis.stateと多くの異なるアプローチを試みたが、これが動作するように見えることはできません。だからソートや一般的なアドバイスを実装するとどんな助けても多くのapprieciatedされてください!

class ProfileCard extends React.Component { 
    render() { 
    return (
     <section className="profile-card"> 
     <figure> 
      <img src={this.props.player.picURL} alt={this.props.player.Name}></img> 
      <article> 
      <ul> 
       <li>{this.props.player.Name}</li> 
       <li>{this.props.player.position}, #{this.props.player.number}</li> 
       <li>{this.props.player.Club}</li> 
       <li>{this.props.player.Height} ({this.props.player.Meters} m)</li> 
       <li>{this.props.player.Age} years old</li> 
      </ul> 
      </article> 
     </figure> 
     </section> 
    ); 
    } 
} 

class Roster extends React.Component { 
    render() { 

    // Store sorted version of data 
    // Where I'd implement selected sorting 
    var sorted = this.props.players.sort(); 

    /* 
    * Create player cards from JSON collection 
    */ 
    var cards = []; 
    sorted.forEach(function(player) { 
     if (player.year > 2000) { 
     cards.push(<ProfileCard player={player} />); 
     } 
    }); 

    return (<div>{cards}</div>); 
    } 
} 

class Sort extends React.Component { 
    render() { 
    return (
     <div className="sort-section"> 
     <h1>Sort by</h1> 
     <div className="pill" id='age'>Age</div> 
     <div className="pill" id='Meters'>Height</div> 
     <div className="pill" id='Name'>Name</div> 
     </div> 
    ) 
    } 
} 

class SortablePlayerTable extends React.Component { 

    render() { 
    /* 
    * Prefix some interestings stats 
    * before roster 
    */ 
    var ages = [], heights = []; 

    this.props.players.forEach(function(player) { 
     if (player.year > 2000) { 
     ages.push(player.Age); 
     heights.push(player.Meters); 
     } 
    }); 
    var avgAge = (ages.reduce((a, b) => a + b)/12).toPrecision(3); 
    var avgHeights = (heights.reduce((a, b) => a + b)/12).toPrecision(3); 

    // Return page with stats data and Roster 
    return (
     <div> 
     <h1>2012 Olympic Men's Basketball Team</h1> 
     <h2>Average Age: {avgAge} years old</h2> 
     <h2>Average Height: 6 ft 7 in ({avgHeights} m)</h2> 
     <Sort/> 
     <Roster 
       players={this.props.players} 
     /> 
     </div> 
    ); 
    } 
}; 

React.render(
    <SortablePlayerTable players={PLAYERS} />, 
    document.getElementById('container') 
); 

ソリューション:

はこれへの道に私を倒してしまった。もう一つは、私がthis.setStateへのアクセスを失ったことが、this.setState is a not a functionエラーを取得維持しました。 ES6矢印関数を使って字句的にバインドして、ハンドラ関数のためにthisが私を救いました。

class ProfileCard extends React.Component { 
    render() { 
    return (
     <section className="profile-card"> 
     <figure> 
      <img src={this.props.player.picURL} alt={this.props.player.Name}></img> 
      <article> 
      <ul> 
       <li>{this.props.player.Name}</li> 
       <li>{this.props.player.position}, #{this.props.player.number}</li> 
       <li>{this.props.player.Club}</li> 
       <li>{this.props.player.Height} ({this.props.player.Meters} m)</li> 
       <li>{this.props.player.Age} years old</li> 
      </ul> 
      </article> 
     </figure> 
     </section> 
    ); 
    } 
} 

class Roster extends React.Component { 
    render() { 
    // Create player cards from sorted, dynamic JSON collection 
    var cards = []; 
    this.props.players.forEach(function(player) { 
     if (player.year > 2000) { 
     cards.push(<ProfileCard player={player} />); 
     } 
    }); 

    return (<div>{cards}</div>); 
    } 
} 

class Sort extends React.Component { 
    sortRoster(field){ 
    var players = this.props.players; 
    this.props.sortRosterStateBy(field, players); 
    } 
    render() { 
    return (
     <div className="sort-section"> 
     <h1>Sort by</h1> 
     <div className="pill" onClick={this.sortRoster.bind(this,'Age')} >Age</div> 
     <div className="pill" onClick={this.sortRoster.bind(this,'Meters')} >Height</div> 
     <div className="pill" onClick={this.sortRoster.bind(this,'Name')} >Name</div> 
     <div className="pill" onClick={this.sortRoster.bind(this,'position')} >Position</div> 
     <div className="pill" onClick={this.sortRoster.bind(this,'number')} >Number</div> 
     <div className="pill" onClick={this.sortRoster.bind(this,'Club')} >Club</div> 
     </div> 
    ) 
    } 
} 

class SortablePlayerTable extends React.Component { 
    state = { 
    'players': this.props.players // default state 
    } 

    sortRosterStateBy = (field, players) => { 
    // Sorting ... 
    var sortedPlayers = players.sort((a, b) => { 
     if (a[field] > b[field]) { 
     return 1; 
     } 
     if (a[field] < b[field]) { 
     return -1; 
     } 
     return 0; 
    }); 

    // Then call setState 
    this.setState({'players': sortedPlayers}); 
    } 

    render() { 
    // Prefix some interestings stats before roster 
    var ages = [], heights = []; 
    this.props.players.forEach(function(player) { 
     if (player.year > 2000) { 
     ages.push(player.Age); 
     heights.push(player.Meters); 
     } 
    }); 
    var avgAge = (ages.reduce((a, b) => a + b)/12).toPrecision(3); 
    var avgHeight = (heights.reduce((a, b) => a + b)/12).toPrecision(3); 

    // Return page with stats data and Roster 
    return (
     <div> 
     <h1>2012 Olympic Men's Basketball Team</h1> 
     <h2>Average Age: {avgAge} years old</h2> 
     <h2>Average Height: 6 ft 7 in ({avgHeight} m)</h2> 
     <Sort players={this.props.players} sortRosterStateBy={this.sortRosterStateBy}/> 
     <Roster players={this.state.players}/> 
     </div> 
    ); 
    } 
}; 

ReactDOM.render(
    <SortablePlayerTable players={PLAYERS} />, 
    document.getElementById('container') 
); 

答えて

10

は、それはあなたの<SortablePlayerTable/>コンポーネントからpropsとしてこの親関数sortByを渡しthis.props.sortBy()

class Sort extends React.Component { 
    sort(field){ 
    this.props.sortBy(field); 
    } 
    render() { 
    return (
     <div className="sort-section"> 
     <h1>Sort by</h1> 
     <div className="pill" id='age' onClick=this.sort.bind(this,'age')>Age</div> 
     <div className="pill" id='Meters' onClick=this.sort.bind(this,'height')>Height</div> 
     <div className="pill" id='Name' onClick=this.sort.bind(this,'name')>Name</div> 
     </div> 
    ) 
    } 
} 

親関数を呼び出すクリックで<Sort/>に各<div/>に関数を取り付けます。

class SortablePlayerTable extends React.Component { 
    state = { 
    players: [] // default state 
    } 
    sortBy(field){ 
    // Your sorting algorithm here 
    // it should push the sorted value by field in array called sortedPlayers 
    // Then call setState 
    this.setState({ 
     players: sortedPlayers 
    }); 
    } 
    render() { 
    // calculate stats 
    return (
     <div> 
     {/* some JSX */} 
     <Sort sortBy={sortBy}/> 
     <Roster 
       players={this.state.players} 
     /> 
     </div> 
    ); 
    } 
}; 

今、ソートされた配列はthis.props.playersとしてあなた<Roster/>コンポーネントに利用できるようになります。 <Roster/>コンポーネント内に並べ替えを行わずに直接配列を描画します。

+0

ありがとうございます!これは間違いなく正しい道に私を置いた。 – Melanchroes