Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
121 views
in Technique[技术] by (71.8m points)

javascript - How am I failing to update a state variable in ReactJS?

I have an event handler in ReactJS designed so that when someone clicks the "Done" checkbox for a calendar entry, the calendar entry is still in the system but it is marked hidden as something not to show. (The calendar is made to allow both one-off and recurring entries, and allow both "Mark this instance done" and "Hide this series" options for recurring entries, but this detail does not concern me here.)

My event handler is intended to copy an array in this.state, makes a clone, push()es an item, and saves the mutated clone as a perhaps cumbersome workaround for directly push()ing an item to an array under this.state. Based on the included console.log() statements, it appears that I am successfully obtaining the item (an integer, here equal to 1), successfully cloning a now-empty array and push()ing the integer into the cloned array, and then failing to modify the empty this.state.hidden_entries.

My code reads:

    hide_instance: function(eventObject) {
      console.log(eventObject);
      var id = parseInt(eventObject.target.id.split('.')[1]);
      console.log(id);
      // var id = eventObject.target.id;
      console.log(this.state.hidden_instances);
      console.log('Cloned: ');
      var hidden_instances = clone(this.state.hidden_instances);
      console.log(hidden_instances);
      hidden_instances.push(id);
      console.log('Before setState()');
      console.log(hidden_instances);
      this.setState({'hidden_instances': hidden_instances});
      console.log(this.state.hidden_instances);
      console.log('After setState()');
      this.forceUpdate();
    },

In my console.log() output I have:

site.js:350 SyntheticEvent {dispatchConfig: Object, dispatchMarker: ".0.3.2:1.1.0.0.0", nativeEvent: MouseEvent, type: "click", target: input#hide-2015-9-18.1.hide-instance…}
site.js:352 1
site.js:354 []
site.js:355 Cloned: 
site.js:357 []
site.js:359 Before setState()
site.js:360 [1]
site.js:362 []
site.js:363 After setState()

My console.log() statements in order say "Before setState()", log the mutated clone, attempt to assign the mutated clone the correct way to this.state.hidden_instances, and then reads back the state variable that was just set, only to see that it remains unchanged.

What should I be doing differently, in this case, to append an item to this.state.hidden_instances, and why is my code failing to mutate the value at that location?

--UPDATE--

I'll post the clone() function, intended for JSON-serializable objects only, but it appears to be returning an empty array when given an empty array; the only way I can see a problem is if it's returning the same empty array instead of a new one. But in case I missed something, here it is:

  var clone = function(original) {
    if (typeof original === 'undefined' ||
      original === null ||
      typeof original === 'boolean' ||
      typeof original === 'number' ||
      typeof original === 'string') {
      return original;
    }
    if (Object.prototype.toString.call(original) === '[object Array]') {
      var result = [];
      for(var index = 0; index < original.length; index += 1) {
        result[index] = clone(original[index]);
      }
    } else {
      var result = {};
      for(var current in original) {
        if (original.hasOwnProperty(current)) {
          result[current] = original[current];
        }
      }
    }
    if (typeof original.prototype !== 'undefined') {
      result.prototype = original.prototype;
    }
    return result;
  }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

From the documentation (in a big red box nonetheless):

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.

and

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

That callback gets passed the updated state afaik.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...