0

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;
  }
2
  • What clone function are you using? Commented Sep 18, 2015 at 18:59
  • @taylorc93 Thank you; I've edited the post to include the definition of clone(). Perhaps I should it by a call to JSON.parse(JSON.stringify(original)). Commented Sep 18, 2015 at 19:43

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.