我正在尝试通过编写一个类似于体育花名册的小型 UI 来学习 React 概念,尤其是 re: 状态和动态 UI。我包含了下面的代码,整个应用程序 + 视觉效果位于 http://codepen.io/emkk/pen/dGYXJO。 .这个应用基本上是根据我之前定义的一组玩家对象创建玩家卡。
我想在点击按钮时对玩家卡片进行排序。我创建了一个 <Sort/>
呈现所述按钮的组件。我会附加事件监听器,但不知道如何在我的 <Roster/>
中反射(reflect)出来零件。我用 this.state
尝试了许多不同的方法但似乎无法让它发挥作用。因此,如果您对实现排序或一般建议有任何帮助,我们将不胜感激!
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 箭头函数词法绑定(bind) 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')
);
最佳答案
为每个 <div/>
附加一个函数在 <Sort/>
单击它调用父函数 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>
)
}
}
传递这个父函数 sortBy
作为props
来自你的 <SortablePlayerTable/>
组件。
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>
);
}
};
现在排序后的数组将对您的 <Roster/>
可用组件为 this.props.players
.直接渲染数组而不在 <Roster/>
中应用任何排序组件。
关于javascript - React.js - 实现组件排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34340987/