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