You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React useEffect中Object.freeze失效如何锁定数组首次渲染值

问题根因

你的代码里firstDiskSlot无法保留初始值,核心是两个写法问题:

  1. 你操作的diskSlot是跨渲染周期共享的同一个数组引用,每次useEffect触发都会执行push往这个数组里追加新内容,本质是持续修改同一个数组对象
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 13:48:12