更大的问题是,当我将状态设置为无效时。我试图在这里解决问题,但遗憾的是,这与我的错误不完全匹配。不过,行为及其失败的方式与我的相同。
我的计数器处于应点击状态更新的状态,这将触发我的分页。但是第一次单击不能正确更新。由于计数器不会按原样增加,因此它会抛出下面的pagination
函数。底部的小提琴将它们全部显示出来。
这就是我想要的:https://jsfiddle.net/drumgod/n5u2wwjg/262413/一个计数器,该计数器应增加。
这种提琴奏效了,所以我的问题必须在代码中的其他地方。基本思路是这样:
1.click按钮使计数器增加30
2。分页的分片数组
3。项目出现在页面上
问题是:
调用pagination
并且计数器不增加。
pagination
内部的逻辑已关闭。
项目没有出现在页面上。
示例代码:
//should add 30 to state each time but does not on first click
countBy30() {
this.setState((prevState => ({
counter: prevState.counter + 30
})))
return this.state.counter
}
//func to do pagination by slicing arr
paginate(arr) {
// calling here should add 30 but does not on click
let count = this.countBy30()
//slices up array - counter seems to screw up this slicing?
let sliceStart = count - 30
let sliceEnd = count
let chunk = arr.slice(sliceStart, sliceEnd)
return chunk
}
https://jsfiddle.net/drumgod/705t1oc8/55/
在小提琴中,单击按钮Next 30
时,数字确实在渲染中增加,但是直到第二次单击时,列表才会更改。这是因为由于某些原因,pagination
函数中的切片被关闭了30。
(由于小提琴非常忙,因此我认为上面的小提琴直接进入countBy30
是可行的。)
答案 0 :(得分:1)
问题在于paginate
假设countBy30
返回新的状态值,但是state是异步更新的,因此countBy30
返回的是旧值,然后分页将其用于对状态进行其他更改。
您应该重新编写代码,以便整体确定新状态,然后在单个“ setState”调用中进行设置(即updatePageState
应该设置chunkComments
和counter
)
这里显示的是jsfiddle。
主要变化是:
在构造函数中添加了以下内容:
this.updatePageState = this.updatePageState.bind(this);
将您的then
更改为:
.then(items => {
// filter out undefined
let comments = items.filter(obj => obj)
console.log('c', comments)
// push all comments to state
this.setState({
fullComments: [...comments]
})
// paginate comments on load
let obj = this.paginate(this.state.fullComments)
console.log('original obj', obj)
// set first 30 to state
this.setState({
chunkComments: obj
})
})
收件人:
.then(items => {
// filter out undefined
let comments = items.filter(obj => obj)
console.log('c', comments)
// push all comments to state
let counterAndChunk = this.paginate(comments);
this.setState({
fullComments: [...comments],
...counterAndChunk
});
})
并从以下位置更改了paginage
和updatePageState
:
paginate(arr) {
//increment and get current count
let count = this.countBy30()
console.log('count', count)
let sliceStart = count - 30
/* console.log('start', sliceStart)
*/ let sliceEnd = count
/* console.log('end', sliceEnd) */
let chunk = arr.slice(sliceStart, sliceEnd)
/* console.log('chunk', chunk) */
return chunk
}
updatePageState(arr) {
let obj = this.paginate(arr)
//console.log('paginate obj', obj)
this.setState({
chunkComments: obj
})
//console.log('new state', this.state)
}
收件人:
paginate(arr) {
//increment and get current count
let count = this.state.counter + 30;
console.log('count', count)
let sliceStart = count - 30
/* console.log('start', sliceStart)
*/ let sliceEnd = count
/* console.log('end', sliceEnd) */
let chunk = arr.slice(sliceStart, sliceEnd)
/* console.log('chunk', chunk) */
return {chunkComments: chunk, counter: count};
}
updatePageState() {
let newState = this.paginate(this.state.fullComments)
//console.log('paginate obj', obj)
this.setState(newState)
//console.log('new state', this.state)
}
并更改:
<button onClick = {() => {this.updatePageState(this.state.fullComments)}} >
收件人:
<button onClick = {this.updatePageState}>
答案 1 :(得分:1)
我可以通过两种方式实现这种功能。
您可以决定只使用一种反应组件来处理计数器和分页。就像我在下面显示的一样。
export default class PaginationWithCounter extends React.Component {
constructor(props) {
super(props);
//initialize counter and data
this.state = {
counter: 30,
data: []
};
this.incrementCounter = this.incrementCounter.bind(this);
}
componentDidMount() {
//make ajax call and load data
}
//reacts to click events
incrementCounter() {
this.setState(prevState => {counter: prevState.counter + 30});
}
render() {
const {data, counter} = this.state;
const page = data.slice(counter - 30, counter); //load up to 30 items
//render the page and the button
return (
<div>
<ul>
{/**iterate through the page array and display them*/}
</ul>
<button onClick={this.incrementCounter}>increment{counter}</button>
</div>
);
}
}
您还可以决定具有分页组件和计数器组件。在这种情况下,计数器组件会从分页组件接受分页回调道具,只要有点击,便会调用该分页回调道具。
答案 2 :(得分:-1)
countBy30() {
this.setState((prevState => ({
counter: prevState.counter + 30
}
应该是
countBy30() {
this.setState({counter: this.state.counter + 30})
}