Bill Walters
Bill Walters

Reputation: 125

State Not Updating Immediately ReactJS

I can't figure out what I'm doing wrong here. I have an Event that triggers a function to change the state of several values, so that I can fire off an API call; however, the first time the function runs the states don't change. The second time the function runs the state change from the previous run is set. What could be causing this delay?

So as you can see below handleFilterChange receives values from the Event, and I can verify that the values are being received properly; however, if I check the state's value immediately after being set I can see that it's undefined. When the event comes in a second time; however, I can see that the original state change has now occurred, but the second one hasn't. So why would setState have to be called twice to actually set the state?

var GridView = React.createClass({
  getInitialState: function() {
    window.addEventListener("scroll", this.handleScroll);
    return {
      data: [],
      page: 0,      //for pagination
      loadingFlag: false,
    };
    },

  getMainFeed: function() {

...

 }, //end function
 getFilteredItems: function() {
  ...

}, //end function
  componentWillMount: function() {

  },
  listenForFilterChange: function() {
    window.addEventListener("selectedFilterChange", this.handleFilterChange, false);
  },
  componentWillUnmount: function() {
    window.removeEventListener("selectedFilterChange", this.handleFilterChange, false);
  },
  handleFilterChange: function(filter) {
   //alert(filter.detail.filterType);
   //Convert Data for getFilteredItems
   //(EventType, Category, Buy, Inspiration) {
   switch (filter.detail.filterType) {
     //alert(filter.detail.filterType);
    case 'category':
      this.setState({
        itemCategory: filter.detail.filterSelected,
      });
      break;
    case 'event':
      this.setState({
        eventType: filter.detail.filterSelected,
      });
      break;
    case 'type':
      if (0){
        this.setState({
          filterBuy: 1,
          filterInspiration: 0,
        });
      }
      if (1){
        this.setState({
          filterBuy: 0,
          filterInspiration: 1,
        });
      }
      if (2){
        this.setState({
          filterBuy: 1,
          filterInspiration: 1,
        });
      }
      break;
    case 'trending':
      this.setState({
        itemCategory: filter.detail.filterSelected,
      });
      break;
   }

   this.getFilteredItems();
 },
  componentDidMount: function() {
    this.listenForFilterChange();
...
  },
  handleScroll:function(e){
...
  },
  componentDidUpdate: function() {
...
  },
  render: function() {
      return (
        <div id="feed-container-inner">
          <GridMain data={this.state.data} />
        </div>

      );
    }
  });

Upvotes: 2

Views: 1399

Answers (2)

David Hellsing
David Hellsing

Reputation: 108472

setState is asynchronous, so the changes wont be reflected in the state immediately:

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.

If you need to confirm the state or do logic based on the state change, use the callback argument as described here.

Upvotes: 2

Fran&#231;ois Richard
Fran&#231;ois Richard

Reputation: 7035

setState does not have to be called twice. Reading your code I can't deduce what's wrong exactly but I can advise this:

  1. Console.log your state in the render function if you want to know what's in it.
  2. Check again what's in your event (what case is triggered and if it's really triggered). 3.Check if another function (another setState) is not overriding the state you want to set in handlefilterChange.

My bet is that your filter is not receiving the right values, first receiving undefined filter.detail.filterSelected then another one defined... Check what's in filter.detail.filterSelected I see in the comment you only checked for filter.detail.filterType

Anyway your problem is not due to setState but from your data I'm pretty sure.

Let me know if it helped

Upvotes: 0

Related Questions