简体   繁体   中英

React state value not updating

I would like to update the value of topicsVisited state by passing the value from variable named topicsVisited . However, its not updating the values. When user visits the end of the topic page it should push the topicID value to the array and that array value will be stored in localstorage and transferred to the state.

import {React, ReactDOM} from '../../../../build/react';

import SelectedTopicPageMarkup from './selected-topic-page-markup.jsx';
import NextPrevBtn from './next-prev-btn.jsx';

export default class SelectedTopicPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      topicPageNo: 0,
      total_selected_topic_pages: 1,
      topicsVisited: []
    };
  };
  navigateBack(topicPageNo) {
    if (this.state.topicPageNo > 0) {
      topicPageNo = this.state.topicPageNo - 1;
    } else {
      topicPageNo = 0;
    }
    this.setState({topicPageNo: topicPageNo});
  };
  navigateNext(totalPagesInSelectedTopic) {
    let topicPageNo;
    if (totalPagesInSelectedTopic > this.state.topicPageNo + 1) {
      topicPageNo = this.state.topicPageNo + 1;
    } else if (totalPagesInSelectedTopic == this.state.topicPageNo + 1) {
      let topicsVisited = JSON.parse(localStorage.getItem('topicsVisited')) || [];
      topicsVisited.push(parseInt(this.props.topicsID));
      localStorage.setItem("topicsVisited", JSON.stringify(topicsVisited));
      this.setState({topicsVisited: topicsVisited});
      console.log(this.state.topicsVisited);
      this.props.setTopicClicked(false);
    } else {
      topicPageNo = this.state.topicPageNo;
    }
    this.setState({topicPageNo: topicPageNo});
  };

  render() {
    let topicsID = this.props.topicsID;
    let topicPageNo = this.state.topicPageNo;
    return (
      <div>
        {this.props.topicPageData.filter(function(topicPage) {
          // if condition is true, item is not filtered out
          return topicPage.topic_no === topicsID;
        }).map(function(topicPage) {
          let totalPagesInSelectedTopic = topicPage.topic_pages.length;
          return (
            <div>
              <div>
                <SelectedTopicPageMarkup headline={topicPage.topic_pages[0].headline} key={topicPage.topic_no}>
                  {topicPage.topic_pages[topicPageNo].description}
                </SelectedTopicPageMarkup>
              </div>
              <div>
                <NextPrevBtn moveNext={this.navigateNext.bind(this, totalPagesInSelectedTopic)} key={topicPage.topic_no} moveBack={this.navigateBack.bind(this, topicPageNo)}/>
              </div>
            </div>
          );
        }.bind(this))}
      </div>
    );
  };
};

The setState docs talk about two important things:

There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

and

The second (optional) parameter is a callback function that will be executed once setState is completed and the component is re-rendered.

You might want to consolidate your two setState calls or use a callback to do the work you want to be done after the state change.

The callback would look something like:

this.setState({topicsVisited: topicsVisited}, function() {
    console.log(this.state.topicsVisited);
    this.props.setTopicClicked(false);
}.bind(this));

Isn't the right code this setState method/function, instead of trying to change the state variable directly?

this.setState({
  topicPageNo: 0,
  total_selected_topic_pages: 1,
  topicsVisited: []
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM