[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
复制代码

 

posted @   Zhentiw  阅读(932)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2014-11-29 [AngularJS] Accessing Scope from The Console
2014-11-29 [AngularJS] Accessing Data in HTML -- controllerAs, using promises
2014-11-29 [AngularJS] Directive Definition Objects (DDO)
2014-11-29 [AngularJS] Using the Angular scope $destroy event and method
点击右上角即可分享
微信分享提示