计数器状态增加不更新

时间:2019-01-04 22:06:08

标签: reactjs

更大的问题是,当我将状态设置为无效时。我试图在这里解决问题,但遗憾的是,这与我的错误不完全匹配。不过,行为及其失败的方式与我的相同。

我的计数器处于应点击状态更新的状态,这将触发我的分页。但是第一次单击不能正确更新。由于计数器不会按原样增加,因此它会抛出下面的pagination函数。底部的小提琴将它们全部显示出来。

这就是我想要的:https://jsfiddle.net/drumgod/n5u2wwjg/262413/一个计数器,该计数器应增加。

这种提琴奏效了,所以我的问题必须在代码中的其他地方。基本思路是这样:

1.click按钮使计数器增加30

2。分页的分片数组

3。项目出现在页面上

问题是:

  1. 调用pagination并且计数器不增加。

  2. pagination内部的逻辑已关闭。

  3. 项目没有出现在页面上。

示例代码:

    //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是可行的。)

3 个答案:

答案 0 :(得分:1)

问题在于paginate假设countBy30返回新的状态值,但是state是异步更新的,因此countBy30返回的是旧值,然后分页将其用于对状态进行其他更改。

您应该重新编写代码,以便整体确定新状态,然后在单个“ setState”调用中进行设置(即updatePageState应该设置chunkCommentscounter

这里显示的是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
                    });
                })

并从以下位置更改了paginageupdatePageState

    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})
}