我制作了2个组件: 1)内容(使用fetch()显示数据) 2)分页(每页共5页16个对象)
我制作了两个名为start:0
和end:16
的状态变量。现在,每当用户点击页码时,我想从分页组件向内容组件注入开始和结束状态变量。
将开始和结束变量传递给内容的逻辑如下: 最初结束= 16 * 1(1乘以因为第1页)和start = end-16,即start = 0
结束= 16 * 2(2因为第2页而倍增)和start = end-16,即start = 16
这些开始和结束变量在内容组件的.slice()
中传递,以便onClick:
第1页应显示第0至16条
第2页应显示第16至32条,依此类推至第5页
以下是分页代码和内容组件:
content.js:
class Content extends Component {
constructor(props){
super(props);
this.state = {
matches:[],
loading:true,
callmatchinfo: false,
matchid:''
};
}
componentDidMount(){
fetch('api/matches')
.then(res => res.json())
.then(res => {
console.log(res)
this.setState({
matches:res.slice(this.props.start,this.props.end), <---add new start and end everytime we click on new page number
loading:false
});
})
}
viewstats(matchid){
this.setState({
callmatchinfo: true,
matchid: matchid
});
}
rendermatchinfo(){
return <Matchinfo matchid={this.state.matchid} />
}
renderMatches() {
return this.state.matches.map(match => {
return (
<div className="col-lg-3">
<div id="content">
<p className="match">MATCH {match.id}</p>
<h4>{match.team1}</h4>
<p>VS</p>
<h4>{match.team2}</h4>
<div className="winner">
<h3>WINNER</h3>
<h4>{match.winner}</h4>
</div>
<div className="stats">
<button type="button" onClick= {()=>{this.viewstats(match.id)}} className="btn btn-success">View Stats</button>
</div>
</div>
</div>
);
})
}
render() {
if (this.state.loading) {
return <img src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif" />
}
else if(this.state.callmatchinfo){
return <Matchinfo match_id={this.state.matchid} />
}
return (
<div>
<div className="row">
{this.renderMatches()}
</div>
<div className="row">
{this.state.callmatchinfo ? this.rendermatchinfo() : ''}
</div>
</div>
);
}
}
export default Content;
pagination.js:
class Pagination extends Component {
constructor(props){
super(props)
this.state = {
start:0,
end:16
};
}
handleClick(){
this.setState{
end:getpagenumber()*16,
start:end-16
}
}
getpagenumber(val){
return val;
}
render() {
let{start,end} = this.state;
return (
<div>
<Content/>
<div className="container">
<ul className="pagination">
<li {this.getpagenumber(1)} onClick={this.handleClick}><a href="#">1</a></li>
<li {this.getpagenumber(2)} onClick={this.handleClick}><a href="#">2</a></li>
<li {this.getpagenumber(3)} onClick={this.handleClick}><a href="#">3</a></li>
<li{this.getpagenumber(4)} onClick={this.handleClick}><a href="#">4</a></li>
<li{this.getpagenumber(5)} onClick={this.handleClick}><a href="#">5</a></li>
</ul>
</div>
</div>
);
}
}
export default Pagination;
答案 0 :(得分:3)
您需要父组件来传达这两个组件,例如:
class ParentComponent extends Component {
state = {
start: 0,
end: 16,
};
onChangePagination = (start, end) => {
this.setState({
start,
end,
});
};
render() {
const { start, end } = this.state;
return (
<div>
<Content start={start} end={end} />
<Pagination
onChange={this.onChangePagination} />
</div>
);
}
}
您需要在分页组件中进行另一项更改,即在值更改时调用onChange
回调。
handleClick() {
const end = (getpagenumber() * 16);
const start = (end - 16);
this.setState({
end: end,
start: start,
});
this.props.onChange(start, end);
}
renderMatches() {
// Slide matches before looping, props will have the
// values from the pagination component.
return this.state.matches.slice(this.props.start, this.props.end)
.map(match => (
<div className="col-lg-3">
<div id="content">
<p className="match">MATCH {match.id}</p>
<h4>{match.team1}</h4>
<p>VS</p>
<h4>{match.team2}</h4>
<div className="winner">
<h3>WINNER</h3>
<h4>{match.winner}</h4>
</div>
<div className="stats">
<button
type="button"
onClick={ () => this.viewstats(match.id) }
className="btn btn-success">
View Stats</button>
</div>
</div>
</div>
)
);
}
你可能想要从Pagination组件中删除本地状态,你真的不需要它。
答案 1 :(得分:2)
Crysfel拥有最简单的正确解决方案,因为您需要一个父组件来管理数据,并将其作为道具传递给子组件,但还有另一种方法可以更好地适应大型项目。
如果您只是在学习,或者您正在做一些小事,那么一定不要使用它,但Redux是另一种方式。
简而言之,它是一个非常复杂的水桶,可以放置你的状态。现在,不是关注自己状态的组件,而是将非表示状态放在redux存储中,并使用选择器从存储中读取组件。
在您的情况下,当您点击Pagination
以改变商店时,您将触发操作,这会导致组件侦听更改的任何数据以进行更新。
答案 2 :(得分:1)
如果您想传递------WebKitFormBoundary62hryFjhCKbptVPz
Content-Disposition: form-data; name="MediaInfo"
[{"ID":11,"LastName":"Mazzo","FirstName":"Bob","DeviceID":"46","InstanceID":9,"PatientDOB":"1967-05-01","FileName":"Bob and Chris Cardillo.jpg","FileSize":399030,"ExamDate":"1/31/2018","UID":11,"SessionID":"sessionID=cfe351c8-63f8-40b0-909d-d9a5991f6a70"}]
------WebKitFormBoundary62hryFjhCKbptVPz
Content-Disposition: form-data; name="files[]"; filename="Bob and Chris Cardillo.jpg"
Content-Type: image/jpeg
和start
道具,只需执行以下操作:
end
这应该回答您如何将道具传递给....
render() {
let{start,end} = this.state;
return (
<div>
<Content start={start} end={end} />
.....
组件的具体问题。
这可能对你有所帮助,但我认为无论如何你应该考虑一些代码重构。
答案 3 :(得分:1)
您需要传递一个将状态从Content
更新为Pagination
的函数:
将此代码移至Content
中的单独函数:
updatePage(start, end) {
fetch('api/matches')
.then(res => res.json())
.then(res => {
console.log(res)
this.setState({
// Add new start and end everytime we click on new page number.
matches: res.slice(start, end),
loading: false,
});
});
}
然后将其作为道具传递给Pagination
:
<Pagination updatePage={this.updatePage} />
然后,每次更新Pagination
中的页面时,请致电this.props.updatePage
:
handleClick() {
const end = this.getpagenumber() * 16;
const start = end - 16;
this.setState({
end,
start,
});
this.props.updatePage(start, end);
}
<强>更新强>
简单更新到Content
只能获取所有数据一次,然后使用props来对每个渲染上的匹配进行切片:
class Content extends Component {
constructor(props){
super(props);
this.state = {
matches: [],
loading: true,
callmatchinfo: false,
matchid: '',
};
}
componentDidMount() {
fetch('api/matches')
.then(res => res.json())
.then(res => {
// On mount, load all data and save it in state.
this.setState({
allData: res,
loading: false,
});
});
}
renderMatches() {
// Here we use slice on all the data and only return
// 15 matches at a time for rendering.
return this.state.allData.slice(this.props.start, this.props.end)
.map(match => (
<div className="col-lg-3">
<div id="content">
<p className="match">MATCH {match.id}</p>
<h4>{match.team1}</h4>
<p>VS</p>
<h4>{match.team2}</h4>
<div className="winner">
<h3>WINNER</h3>
<h4>{match.winner}</h4>
</div>
<div className="stats">
<button
type="button"
onClick={
() => { this.viewstats(match.id) }
}
className="btn btn-success">
View Stats</button>
</div>
</div>
</div>
);
})
}
render() {...}
}
export default Content;