Skip to main content
add note about array change proposal
Source Link
T.J. Crowder
  • 1.1m
  • 196
  • 2k
  • 1.9k

Once the change array by copy proposal is widely supported (it's at Stage 3, so should be finding its way into JavaScript engines), you'll be able to do this with the new with method:

// Using a Stage 3 proposal, not widely supported yet as of Nov 17 2022
this.setState({images: this.state.images.with(4, updatedImage)});

Until then, Object.assign does the job:

Object.assign does the job:

Once the change array by copy proposal is widely supported (it's at Stage 3, so should be finding its way into JavaScript engines), you'll be able to do this with the new with method:

// Using a Stage 3 proposal, not widely supported yet as of Nov 17 2022
this.setState({images: this.state.images.with(4, updatedImage)});

Until then, Object.assign does the job:

added 489 characters in body
Source Link
T.J. Crowder
  • 1.1m
  • 196
  • 2k
  • 1.9k

There's no syntax that provides that, no. Object.assign does the job:

this.setState({images: Object.assign([...[], this.state.images]images, {4: updatedImage}));

...but involves a temporary object (the one at the end). Still, just the one temp object... If you do this with slice and spreading out arrays, it involve several more temporary objects (the two arrays from slice, the iterators for them, the result objects created by calling the iterator's next function [inside the ... handle], etc.).

It works because normal JS arrays aren't really arrays1 (this is subject to optimization, of course), they're objects with some special features. Their "indexes" are actually property names meeting certain criteria2. So there, we're spreading out this.state.images into a new array, passing that into Object.assign as the target, and giving Object.assign an object with a property named "4" (yes, it ends up being a string but we're allowed to write it as a number) with the value we want to update.

Live Example:

const a = [0, 1, 2, 3, 4, 5, 6, 7];
const b = Object.assign([...a][], a, {4: "four"});
console.log(b);

If the 4 can be variable, that's fine, you can use a computed property name (new in ES2015):

let n = 4;
this.setState({images: Object.assign([...[], this.state.images]images, {[n]: updatedImage}));

Note the [] around n.

Live Example:

const a = [0, 1, 2, 3, 4, 5, 6, 7];
const index = 4;
const b = Object.assign([], a, {[index]: "four"});
console.log(b);


1 Disclosure: That's a post on my anemic little blog.

2 It's the second paragraph after the bullet list:

An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232-1.

So that Object.assign does the same thing as your create-the-array-then-update-index-4.

There's no syntax that provides that, no. Object.assign does the job:

this.setState({images: Object.assign([...this.state.images], {4: updatedImage}));

...but involves a temporary object (the one at the end). Still, just the one temp object...

It works because normal JS arrays aren't really arrays1 (this is subject to optimization, of course), they're objects with some special features. Their "indexes" are actually property names meeting certain criteria2. So there, we're spreading out this.state.images into a new array, passing that into Object.assign as the target, and giving Object.assign an object with a property named "4" (yes, it ends up being a string but we're allowed to write it as a number) with the value we want to update.

Live Example:

const a = [0, 1, 2, 3, 4, 5, 6, 7];
const b = Object.assign([...a], {4: "four"});
console.log(b);

If the 4 can be variable, that's fine, you can use a computed property name (new in ES2015):

let n = 4;
this.setState({images: Object.assign([...this.state.images], {[n]: updatedImage}));

Note the [] around n.


1 Disclosure: That's a post on my anemic little blog.

2 It's the second paragraph after the bullet list:

An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232-1.

So that Object.assign does the same thing as your create-the-array-then-update-index-4.

Object.assign does the job:

this.setState({images: Object.assign([], this.state.images, {4: updatedImage}));

...but involves a temporary object (the one at the end). Still, just the one temp object... If you do this with slice and spreading out arrays, it involve several more temporary objects (the two arrays from slice, the iterators for them, the result objects created by calling the iterator's next function [inside the ... handle], etc.).

It works because normal JS arrays aren't really arrays1 (this is subject to optimization, of course), they're objects with some special features. Their "indexes" are actually property names meeting certain criteria2. So there, we're spreading out this.state.images into a new array, passing that into Object.assign as the target, and giving Object.assign an object with a property named "4" (yes, it ends up being a string but we're allowed to write it as a number) with the value we want to update.

Live Example:

const a = [0, 1, 2, 3, 4, 5, 6, 7];
const b = Object.assign([], a, {4: "four"});
console.log(b);

If the 4 can be variable, that's fine, you can use a computed property name (new in ES2015):

let n = 4;
this.setState({images: Object.assign([], this.state.images, {[n]: updatedImage}));

Note the [] around n.

Live Example:

const a = [0, 1, 2, 3, 4, 5, 6, 7];
const index = 4;
const b = Object.assign([], a, {[index]: "four"});
console.log(b);


1 Disclosure: That's a post on my anemic little blog.

2 It's the second paragraph after the bullet list:

An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232-1.

So that Object.assign does the same thing as your create-the-array-then-update-index-4.

added 47 characters in body
Source Link
T.J. Crowder
  • 1.1m
  • 196
  • 2k
  • 1.9k

There's no syntax that provides that, no. Object.assign does the job:

this.setState({images: Object.assign([...this.state.images], {4: updatedImage}));

...but involves a temporary object (the one at the end). Still, just the one temp object...

It works because normal JS arrays aren't really arrays1 (this is subject to optimization, of course), they're objects with some special features. Their "indexes" are actually property names meeting certain criteria2. So there, we're spreading out this.state.images into a new array, passing that into Object.assign as the target, and giving Object.assign an object with a property named "4" (yes, it ends up being a string but we're allowed to write it as a number) with the value we want to update.

Live Example:

const a = [0, 1, 2, 3, 4, 5, 6, 7];
const b = Object.assign([...a], {4: "four"});
console.log(b);

If the 4 can be variable, that's fine, you can use a computed property name (new in ES2015):

let n = 4;
this.setState({images: Object.assign([...this.state.images], {[n]: updatedImage}));

Note the [] around n.


1 Disclosure: That's a post on my anemic little blog.

2 It's the second paragraph after the bullet list:

An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232-1.

So that Object.assign does the same thing as your create-the-array-then-update-index-4.

There's no syntax that provides that, no. Object.assign does the job:

this.setState({images: Object.assign([...this.state.images], {4: updatedImage}));

...but involves a temporary object (the one at the end). Still, just the one temp object...

It works because normal JS arrays aren't really arrays1, they're objects with some special features. Their "indexes" are actually property names meeting certain criteria2. So there, we're spreading out this.state.images into a new array, passing that into Object.assign as the target, and giving Object.assign an object with a property named "4" (yes, it ends up being a string but we're allowed to write it as a number) with the value we want to update.

Live Example:

const a = [0, 1, 2, 3, 4, 5, 6, 7];
const b = Object.assign([...a], {4: "four"});
console.log(b);

If the 4 can be variable, that's fine, you can use a computed property name (new in ES2015):

let n = 4;
this.setState({images: Object.assign([...this.state.images], {[n]: updatedImage}));

Note the [] around n.


1 Disclosure: That's a post on my anemic little blog.

2 It's the second paragraph after the bullet list:

An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232-1.

So that Object.assign does the same thing as your create-the-array-then-update-index-4.

There's no syntax that provides that, no. Object.assign does the job:

this.setState({images: Object.assign([...this.state.images], {4: updatedImage}));

...but involves a temporary object (the one at the end). Still, just the one temp object...

It works because normal JS arrays aren't really arrays1 (this is subject to optimization, of course), they're objects with some special features. Their "indexes" are actually property names meeting certain criteria2. So there, we're spreading out this.state.images into a new array, passing that into Object.assign as the target, and giving Object.assign an object with a property named "4" (yes, it ends up being a string but we're allowed to write it as a number) with the value we want to update.

Live Example:

const a = [0, 1, 2, 3, 4, 5, 6, 7];
const b = Object.assign([...a], {4: "four"});
console.log(b);

If the 4 can be variable, that's fine, you can use a computed property name (new in ES2015):

let n = 4;
this.setState({images: Object.assign([...this.state.images], {[n]: updatedImage}));

Note the [] around n.


1 Disclosure: That's a post on my anemic little blog.

2 It's the second paragraph after the bullet list:

An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232-1.

So that Object.assign does the same thing as your create-the-array-then-update-index-4.

add an example with a computed property name
Source Link
T.J. Crowder
  • 1.1m
  • 196
  • 2k
  • 1.9k
Loading
disclosure, not disclaimer - doh!
Source Link
T.J. Crowder
  • 1.1m
  • 196
  • 2k
  • 1.9k
Loading
added 872 characters in body
Source Link
T.J. Crowder
  • 1.1m
  • 196
  • 2k
  • 1.9k
Loading
added 108 characters in body
Source Link
T.J. Crowder
  • 1.1m
  • 196
  • 2k
  • 1.9k
Loading
deleted 11 characters in body
Source Link
T.J. Crowder
  • 1.1m
  • 196
  • 2k
  • 1.9k
Loading
Source Link
T.J. Crowder
  • 1.1m
  • 196
  • 2k
  • 1.9k
Loading