You can use spread.
const oldList = this.state.list;
let newList = [...oldList];
newList[i] = "foo";
this.setState({ .list: newList });
But the spread will not work if the elements of array are object. Since it will only make a new copy of array that reference to the old object. But in your case, you assign string. So it is primitve type.
So if I'm correct, the spread operator will basically do a deep-cloning
Spread does shallow cloning. Think array spread
same as creating new array and copy all old value to the new array
a = [...b];
is the same as
a = [];
for(let i = 0; i < b.length; i++) a.push(b[i]);
because Vue overrides mutation methods on arrays like push(...)
For push, you can also use spread
a = [...b, 'new item'];
And for pop, you can use splice
a = b.slice(-1, 1);