我正在尝试通过编写类似于体育名册的小型UI来学习React概念,尤其是re:状态和动态UI。我已经在下面添加了代码,整个应用程序+视觉效果位于http://codepen.io/emkk/pen/dGYXJO。这个应用程序基本上是根据我之前定义的玩家对象数组创建玩家卡的。
我想在单击按钮时对玩家卡片进行排序。我创建了一个<Sort/>呈现上述按钮的组件。我将附加事件侦听器,但不知道如何在我的<Roster/>组件中反映出来。我尝试了许多不同的方法,this.state但似乎无法使它起作用。因此,请您对实施排序或常规建议的任何帮助大加赞赏!
<Sort/>
<Roster/>
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箭头函数this为我的处理程序函数进行词法绑定可以挽救我。
this.setState
this.setState is a not a function
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()
<div/>
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/>组件。
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/>组件内部应用任何排序。
this.props.players