React useEffect中Object.freeze失效如何锁定数组首次渲染值
问题根因
你的代码里firstDiskSlot无法保留初始值,核心是两个写法问题:
- 你操作的
diskSlot是跨渲染周期共享的同一个数组引用,每次useEffect触发都会执行push往这个数组里追加新内容,本质是持续修改同一个数组对象 Object.freeze是浅冻结,且你没有对要保存的初始值做独立拷贝,哪怕冻结了变量指向的原对象,后续如果操作同引用的数组还是会影响值(你这里能追加成功,大概率是diskSlot定义在了组件函数外层的模块作用域,且cleanup逻辑里没有重置这个数组,导致每次effect执行都在累积修改同一个数组)
修复方案
用useRef持久化存储首次拿到的初始值,只在第一次获取到有效props.poolInfo时赋值,后续不再修改这个值即可,参考代码如下:
import { useEffect, useRef, useState } from 'react'; // 组件内部定义ref,用来存永久固定的初始值 const firstDiskSlotRef = useRef(null); useEffect(() => { if (props.poolInfo) { setPoolInfo(props.poolInfo); // 仅第一次拿到有效数据时初始化存储,后续不再更新 if (!firstDiskSlotRef.current) { // 创建原数组的独立副本后再冻结,切断和后续props值的引用关联 firstDiskSlotRef.current = Object.freeze([...props.poolInfo.disks_enc_slot]); console.log('固定初始槽位值:', firstDiskSlotRef.current); // 输出永远是[58:0,58:1] } checkAllDiskInDriveGroup(props.poolInfo.disks_enc_slot, driveData); } return () => { setPoolInfo(false); setFormData({ count: { options: [], selectedValue: "" }, disk: { options: [], selectedValue: "" }, }) } }, [props.poolInfo])
关键说明
useRef保存的对象在组件全生命周期内引用固定,不会随组件重渲染被重置- 赋值时用
[...props.poolInfo.disks_enc_slot]创建了原数组的浅拷贝,后续props中传入的磁盘槽位变化,不会影响这份独立存储的初始值 - 非空判断保证初始值只会被赋值一次,后续effect触发不会覆盖原有内容
- 后续需要用到这个固定初始值时,直接读取
firstDiskSlotRef.current即可,值永远是首次渲染拿到的[58:0,58:1]
内容的提问来源于stack exchange,提问作者aliFront
相关产品推荐
相关产品推荐

