[Redux] Avoiding Array Mutations with concat(), slice(), and ...spread

For Redux, you cannot use mutable methods like push, splice. Need to use immutable methods such as concat, slice and ...spread

Html:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <script src="https://wzrd.in/standalone/expect@latest"></script>
  <script src="https://wzrd.in/standalone/deep-freeze@latest"></script>
</head>
<body>

</body>
</html>

push() vs concat()

push: modify the array;

concat: return a new array;

console.clear();
const addCounter = (list)=>{
  list.push(0);
  return list;
}

const testAddCounter = ()=>{
  const beforeList = [];
  const afterList = [0];
  
  deepFreeze(beforeList);
  
  expect(
    addCounter(beforeList)
  ).toEqual(afterList);
}

testAddCounter();
console.log("All tests passing..");

/**
"error"
"TypeError: Can't add property 0, object is not extensible
    at addCounter (fegewebemu.js:5:8)
    at testAddCounter (fegewebemu.js:15:10)
    at fegewebemu.js:18:1"
*/

console.clear();
const addCounter = (list)=>{
  let res = list.concat(0);
  return res;
}

const testAddCounter = ()=>{
  const beforeList = [];
  const afterList = [0];
  
  deepFreeze(beforeList);
  
  expect(
    addCounter(beforeList)
  ).toEqual(afterList);
}

testAddCounter();
console.log("All tests passing..");  // passing

Using ...spread:

console.clear();
const addCounter = (list)=>{
  return [...list, 0];
}

const testAddCounter = ()=>{
  const beforeList = [];
  const afterList = [0];
  
  deepFreeze(beforeList);
  
  expect(
    addCounter(beforeList)
  ).toEqual(afterList);
}

testAddCounter();
console.log("All tests passing.."); // Passing

splice() vs slice()

splice: modfiy array;

slices: return new array;

console.clear();
const removeCounter= (list, index)=>{
   list.splice(index, 1);
  return list;
}

const testRemoveCounter = ()=>{
  const beforeList = [0 ,10,20];
  const afterList = [0, 20];
  
  deepFreeze(beforeList);
  
  expect(
    removeCounter(beforeList, 1)
  ).toEqual(afterList);
}
testRemoveCounter();
console.log("All tests passing.."); 

/**
"error"
"TypeError: Cannot add/remove sealed array elements
    at removeCounter (fegewebemu.js:5:8)
    at testRemoveCounter (fegewebemu.js:15:10)
    at fegewebemu.js:17:1"
*/


console.clear();
const removeCounter= (list, index)=>{
  return list.slice(0, index)
  .concat(list.slice(index+1));
}

const testRemoveCounter = ()=>{
  const beforeList = [0 ,10,20];
  const afterList = [0, 20];
  
  deepFreeze(beforeList);
  
  expect(
    removeCounter(beforeList, 1)
  ).toEqual(afterList);
}
testRemoveCounter();
console.log("All tests passing.."); // Passing

ES6:

console.clear();
const removeCounter= (list, index)=>{
  
  return [
    ...list.slice(0, index),
    ....list.slice(index + 1)
  ];
}

const testRemoveCounter = ()=>{
  const beforeList = [0 ,10,20];
  const afterList = [0, 20];
  
  deepFreeze(beforeList);
  
  expect(
    removeCounter(beforeList, 1)
  ).toEqual(afterList);
}
testRemoveCounter();
console.log("All tests passing.."); // Passing

Modify one element in array:

console.clear();
const incrementCounter = (list, index) => {
   list[index]++;
  
  return list;
};

const testIncrementCounter = ()=>{
  const beforeList = [0 ,10,20];
  const afterList = [0, 11, 20];
  
  deepFreeze(beforeList);
  
  expect(
    incrementCounter(beforeList, 1)
  ).toEqual(afterList);
}
testIncrementCounter();
console.log("All tests passing..");
/**
"error"
"Error: Expected [ 0, 10, 20 ] to equal [ 0, 11, 20 ]
    at Object.assert [as default] (https://wzrd.in/standalone/expect@latest:489:9)
    at Expectation.toEqual (https://wzrd.in/standalone/expect@latest:70:26)
    at testIncrementCounter (fegewebemu.js:16:43)
    at fegewebemu.js:18:1"
*/


console.clear();
const incrementCounter = (list, index) => {
   let res = list.slice(0, index)
     .concat(++list[index])
     .concat(list.slice(index+1));
  
  return res;
};

const testIncrementCounter = ()=>{
  const beforeList = [0 ,10,20];
  const afterList = [0, 11, 20];
  
  deepFreeze(beforeList);
  
  expect(
    incrementCounter(beforeList, 1)
  ).toEqual(afterList);
}
testIncrementCounter();
console.log("All tests passing.."); // Passing

ES6:

console.clear();
const incrementCounter = (list, index) => {
   return [
     ...list.slice(0, index),
     ++list[index],
     ...list.slice(index+1)
   ];
};

const testIncrementCounter = ()=>{
  const beforeList = [0 ,10,20];
  const afterList = [0, 11, 20];
  
  deepFreeze(beforeList);
  
  expect(
    incrementCounter(beforeList, 1)
  ).toEqual(afterList);
}
testIncrementCounter();
console.log("All tests passing.."); // Passing
原文地址:https://www.cnblogs.com/Answer1215/p/5003919.html