2017-11-14 5 views
0

私はスコアボードであるReactアプリを構築しました。右側の+と - の記号を使用して、プレーヤーのスコアからポイントを追加したり削除したりすることができます。現在、選手は自分のIDでソートされています。現在の得点に基づいて選手を並べ替える方法を見つけたいと思います。React - 得点が変化した場合、最高得点でスコアボード上のプレーヤーを並べ替えます。

例えば、あるプレイヤーが他のプレイヤーより高いスコアを取得した場合、そのプレイヤーはランク付けされた行まで移動します。私は私のプロジェクトを表示するCodepenを作った。 onScoreChange機能が実行された後に誰かがどのように選手をソートするか考えているなら、私は本当にそれを感謝します!

CodePen

<div id="container"></div> 
body { 
    background: #d5d5d5; 
    font-family: arial; 
    color: #FAFAFA; 
    text-transform: uppercase; 
} 

.scoreboard { 
    background: #333; 
    width: 700px; 
    margin: 70px auto; 
    box-shadow: 0 4px 0px #333; 
    border-radius: 15px; 

} 

.header { 
    padding: 5px 10px; 
    text-align: center; 
    display: flex; 
    align-items: center; 
    background-color: #222; 
    border-radius: 15px 15px 0 0; 
    border-bottom: solid 2px #444; 
} 

.header h1 { 
    flex-grow: 1; 
    font-size: 1.5em; 
    letter-spacing: 3px; 
    font-weight: normal; 
} 

.player { 
    display: flex; 
    font-size: 1.2em; 
    border-bottom: solid 2px #444; 
    letter-spacing: 2px; 
} 

    .remove-player { 
    visibility: hidden; 
    margin-right: 10px; 
    color: #e57373; 
    cursor: pointer; 
    } 

    .player-name:hover .remove-player { 
    visibility: visible; 
    } 

    .player-name { 
    flex-grow: 1; 
    padding: 20px 10px 10px 10px; 
    } 

    .player-score { 
    width: 190px; 
    background: blue; 
    } 

    .counter { 
    display: flex; 
    } 

    .counter-action { 
    border: none; 
    font-weight: bold; 
    color: #FAFAFA; 
    display: block; 
    padding: 20px 20px; 
    cursor: pointer; 
    -webkit-user-select: none; 
    -moz-user-select: none; 
    -ms-user-select: none; 
    user-select: none; 
    } 

    .counter-action.increment { 
    background: #66BB6A; 
    } 

    .counter-action.increment:hover { 
    background: #549d59; 
    cursor: pointer; 
    } 

    .counter-action.decrement { 
    background: #ef5350; 
    } 

    .counter-action.decrement:hover { 
    background: #c44442; 
    cursor: pointer; 
    } 

    .counter-score { 
    flex-grow: 1; 
    background: #2b2b2b; 
    color: #FAFAFA; 
    text-align: center; 
    font-family: monospace; 
    padding: 10px; 
    font-size: 2em; 
    } 


.add-player-form form { 
    display: flex; 
    background-color: #222; 
    border-radius: 0 0 20px 20px 
} 

    .add-player-form input[type=text] { 
    flex-grow: 1; 
    border-width: 0 0 1px 0; 
    margin: 15px 10px 15px 15px; 
    padding: 10px; 
    border-radius: 5px; 
    background-color: #333; 
    border-style: none; 
    text-shadow: none; 
    text-transform: uppercase; 
    color: #999; 
    letter-spacing: 2px; 
    outline: none; 
    } 

    .add-player-form input[type=text]::-webkit-input-placeholder{ 
    color: #666; 
    letter-spacing: 2px; 
    } 

    .add-player-form input[type=text]:focus{ 
    background-color: #444; 
    } 

    .add-player-form input[type=submit] { 
    display: block; 
    font-size: .6em; 
    margin: 15px 15px 15px 0; 
    padding: 10px; 
    background-color: #333; 
    border-radius: 5px; 
    border: none; 
    color: #999; 
    letter-spacing: 2px; 
    font-weight: bold; 
    text-shadow: none; 
    text-transform: uppercase; 
    } 

    .add-player-form input[type=submit]:hover{ 
    background: #4b71b5; 
    color: #fafafa; 
    cursor: pointer; 
    } 

var PLAYERS = [ 
    { 
    name: "Mary Miller", 
    score: 22, 
    id: 1, 
    }, 
    { 
    name: "Ellie Grace", 
    score: 20, 
    id: 2, 
    }, 
    { 
    name: "Ben Pine", 
    score: 18, 
    id: 3, 
    }, 
    { 
    name: "Rachel Slater", 
    score: 17, 
    id: 4, 
    }, 
    { 
    name: "Lisette Ven", 
    score: 10, 
    id: 5, 
    }, 
]; 

var nextId = 6; 

var AddPlayerForm = React.createClass({ 
    propTypes: { 
    onAdd: React.PropTypes.func.isRequired, 
    }, 

    getInitialState: function() { 
    return { 
     name: "", 
    }; 
    }, 

    onNameChange: function(e) { 
    this.setState({name: e.target.value}); 
    }, 

    onSubmit: function(e) { 
    e.preventDefault(); 

    this.props.onAdd(this.state.name); 
    this.setState({name: ""}); 
    }, 


    render: function() { 
    return (
     <div className="add-player-form"> 
     <form onSubmit={this.onSubmit}> 
      <input type="text" value={this.state.name} onChange={this.onNameChange} /> 
      <input type="submit" value="Add Player" /> 
     </form> 
     </div> 
    ); 
    } 
}); 

function Header(props) { 
    return (
    <div className="header"> 
     <h1>{props.title}</h1> 
    </div> 
); 
} 

Header.propTypes = { 
    title: React.PropTypes.string.isRequired, 
    players: React.PropTypes.array.isRequired, 
}; 

function Counter(props) { 
    return (
    <div className="counter"> 
     <button className="counter-action decrement" onClick={function() {props.onChange(-1);}} > - </button> 
     <div className="counter-score"> {props.score} </div> 
     <button className="counter-action increment" onClick={function() {props.onChange(1);}}> + </button> 
    </div> 
); 
} 

Counter.propTypes = { 
    score: React.PropTypes.number.isRequired, 
    onChange: React.PropTypes.func.isRequired, 
} 

function Player(props) { 
    return (
    <div className="player"> 
     <div className="player-name"> 
     <a className="remove-player" onClick={props.onRemove}>✖</a> 
     {props.name} 
     </div> 
     <div className="player-score"> 
     <Counter score={props.score} onChange={props.onScoreChange} /> 
     </div> 
    </div> 
); 
} 

Player.propTypes = { 
    name: React.PropTypes.string.isRequired, 
    score: React.PropTypes.number.isRequired, 
    onScoreChange: React.PropTypes.func.isRequired, 
    onRemove: React.PropTypes.func.isRequired, 
}; 



var Application = React.createClass({ 
    propTypes: { 
    title: React.PropTypes.string, 
    initialPlayers: React.PropTypes.arrayOf(React.PropTypes.shape({ 
     name: React.PropTypes.string.isRequired, 
     score: React.PropTypes.number.isRequired, 
     id: React.PropTypes.number.isRequired, 
    })).isRequired, 
    }, 

    getDefaultProps: function() { 
    return { 
     title: "Foosball Scoreboard", 
    } 
    }, 

    getInitialState: function() { 
    return { 
     players: this.props.initialPlayers, 
    }; 
    }, 

    onScoreChange: function(index, delta) { 
    this.state.players[index].score += delta; 
    this.setState(this.state); 
    }, 

    onPlayerAdd: function(name) { 
    this.state.players.push({ 
     name: name, 
     score: 0, 
     id: nextId, 
    }); 
    this.setState(this.state); 
    nextId += 1; 
    }, 

    onRemovePlayer: function(index) { 
    this.state.players.splice(index, 1); 
    this.setState(this.state); 
    }, 

    // reorderPlayers 

    render: function() { 
    return (
     <div className="scoreboard"> 
     <Header title={this.props.title} players={this.state.players} /> 

     <div className="players"> 
      {this.state.players.map(function(player, index) { 
      return (
       <Player 
       onScoreChange={function(delta) {this.onScoreChange(index ,delta)}.bind(this)} 
       onRemove={function() {this.onRemovePlayer(index)}.bind(this)} 
       name={player.name} 
       score={player.score} 
       key={player.id} /> 
      ); 
      }.bind(this))} 
     </div> 
     <AddPlayerForm onAdd={this.onPlayerAdd} /> 
     </div> 
    ); 
    } 
}); 



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

答えて

2

は、単にアレイ毎回スコアをソートするonScoreChange機能でArray.sort機能を使用するには、働いていたこの

onScoreChange: function(index, delta) { 
    let players = [...this.state.players] 

    players[index] = Object.assign({},players[index]) 
    // Or if you can use object spread then: players[index] = {...players[index]} 
    players[index].score += delta; 

    // Use Array.sort function like this 
    players.sort((a,b) => b.score - a.score) 
    this.setState({players}); 
    }, 
+1

のように変更されました!私はReactには新しく、それはうまくいくとは思わなかった。ご協力いただきありがとうございます! @Prakash sharma –

+1

あなたが配列(その深い入れ子にされたオブジェクト)を広げても、ここで状態を突然変異させているだけであることに注意してください。別のものでは、sortは新しい配列を返さず、現在の配列で動作します。もう一つ、 'score'は文字列なので、数値ソートを行うには' number'にキャストする必要があります。 –

+0

@ Sag1v Yupp。完了:) –

関連する問題