前端问题 为什么我的 fliter 能改变原数组?网上全部都是 filter 不改变原数组....

2022-05-25 09:18:35 +08:00
 particlec

const [selectProductKey, setSelectProductKey] = useState([]);

// 搜索框 key 匹配数组 productKey const matchProductKey = key => { let temporaryArr = [...productKeyArr]; temporaryArr.filter(obj => obj.slice(key) !== -1); setSelectProductKey(temporaryArr); };

onSearch={e => {matchProductKey(e);}}

// 这里的 selectProductKey 数组确实被筛选了 {selectProductKey.map(key => (<Select.Option value={key}>{key}</Select.Option>))}

2647 次点击
所在节点    问与答
27 条回复
liujunhn
2022-05-25 09:24:09 +08:00
你不是已经用 setSelectProductKey(temporaryArr)把 filter 之后的数组给到 select Product Key 了吗?
particlec
2022-05-25 09:27:28 +08:00
// 这里 使用了 filter ,按道理 temporaryArr 不会被改变
temporaryArr.filter(obj => obj.slice(key) !== -1);

// selectProductKey 按道理也不会改变啊
setSelectProductKey(temporaryArr);
particlec
2022-05-25 09:34:57 +08:00
const [selectProductKey, setSelectProductKey] = useState([]);

// 这是一个搜索框的功能,通过 key 模糊筛选
const matchProductKey = key => {
let temporaryArr = [...productKeyArr];
// 这里 使用了 filter ,按道理原数组 temporaryArr 不会被改变
temporaryArr.filter(obj => obj.slice(key) !== -1);
// 如果原数组没有改变 selectProductKey 也不会改变
setSelectProductKey(temporaryArr);
};


matchProductKey(e);


// 但是实际界面 这里 selectProductKey 确实数据过滤了
{selectProductKey.map(key => (
<Select.Option value={key}>{key}</Select.Option>
))}
重新描述一下,第一次发帖问题顺序有点乱
shabbyin
2022-05-25 09:36:07 +08:00
原数组没改变
你用 setSelectProductKey 方法把过滤后的新数组通过设置为新的 state 指向了
此时你访问的 state 已经是新数组了 老数组你没有保存其堆地址的话 就再也访问不到了
particlec
2022-05-25 09:40:21 +08:00
setSelectProductKey(temporaryArr) state 不是会指向 temporaryArr 吗?为啥会指向新数组呢
wu67
2022-05-25 09:41:32 +08:00
array 的高级方法不改变原值, 意思是: 直接改基础类型 无效. 直接改引用 无效. 但是如果你改引用类型里面的 下标 /属性 值, 有效.
rabbbit
2022-05-25 09:47:18 +08:00
let temporaryArr = [...productKeyArr];
这里创建了新数组 temporaryArr
setSelectProductKey(temporaryArr);
这里新数组被赋值给 selectProductKey
shabbyin
2022-05-25 09:47:44 +08:00
@particlec
这块有一个比较可疑的点
filter 遍历的元素应该不是一个基础类型数据,而是引用类型的数据
另外 你这个数组结构我属实有点没看懂
filter 里用了 obj.slice 方法,是不是可以认为 obj 是一个数组
那么按道理说你这个 selectProductKey 应该是一个二维数组吧
那么这种情况下怎么做到一层 map 实现 dom 渲染的
particlec
2022-05-25 09:51:30 +08:00
console.log(temporaryArr);
temporaryArr =['a1k8ySyJMPn', 'a1mXxl1AJOa', 'a1T2vgkO3L7', 'a1xaURWP4fN', 'a1oCgqebiVr', 'a1OSLcORuwH', 'a1StepeOwMD', 'a1oAnKZ7Clp', 'a1M4rSzH9wr', 'a1Y2RSRhB8b']
Shy07
2022-05-25 09:52:30 +08:00
const productKeyArr = ['010', '020', '030']
const temporaryArr = [...productKeyArr]
temporaryArr.filter(obj => obj.includes('2'))
console.log(temporaryArr)

代码精简一下大概这样子,浏览器运行结果是 ['010', '020', '030']
这部分没问题,建议看看 productKeyArr 是不是被修改了
rabbbit
2022-05-25 09:53:31 +08:00
建议找个 codepen 之类的贴下代码
particlec
2022-05-25 09:56:32 +08:00
嗯,slice 确实要改成 includes ,主要是那个引用问题还不是很理解
fengfuliu
2022-05-25 10:00:40 +08:00
@particlec 问题就是你调用了 slice 导致的 slice 返回被裁减过的数组 因为是浅拷贝 影响到了 temporaryArr 吧
sweetcola
2022-05-25 10:01:23 +08:00
slice 返回的是数组,数组 !== -1 那不是全部 true 吗...
particlec
2022-05-25 10:01:35 +08:00
我打印了一下,发现原数组 temporaryArr 确实没有改变,就是 setSelectProductKey(temporaryArr);为啥没指向原数组
sweetcola
2022-05-25 10:06:24 +08:00
@particlec 你用了 Spread 语法([...productKeyArr]),temporaryArr 就已经是一个新的数组了,不会指向原数组。
particlec
2022-05-25 10:08:48 +08:00
不是 slice 的问题,换成 includes 也会出现同样的问题,应该跟 setSelectProductKey 有关
particlec
2022-05-25 10:23:21 +08:00
@shabbyin “老数组你没有保存其堆地址的话 就再也访问不到了” 请教 老数组为啥访问不到,setSelectProductKey 为什么会指向新数组呢
disk
2022-05-25 11:45:11 +08:00
代码不全,看不出更多东西,建议自己跑个 debug 看下
zhaomeicheng
2022-05-25 14:13:55 +08:00
主题支持 Markdown 格式的,建议代码别直接贴,看不清楚...

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/855112

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX