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

React useState定义的变量无法实现非响应式值拷贝如何解决?

问题原因解析

你遇到的现象和对象拷贝方法无关,是React函数组件的渲染机制导致的:

  • 每次调用setNumber更新状态后,整个App函数组件都会重新执行
  • 重渲染时你定义的3个拷贝变量都会重新创建,基于更新后的最新number状态值做拷贝,所以自然会和最新状态保持一致
  • 不存在你误以为的「拷贝变量和原状态有响应式绑定」的情况,只是每次重渲染时拷贝变量都被覆盖为了最新状态的副本,才会看起来同步更新
解决方案

你需要存储的是状态的初始值,所以要把初始值单独存储,避免每次重渲染被覆盖,有两种常用实现方式:

方案1:初始值为静态值时,提取为外部常量

把初始值提到组件外部定义,组件内所有用到初始值的地方都引用这个常量即可:

import { useState } from "react";
import "./styles.css";

// 静态初始值提到组件外部,不会随组件重渲染变化
const INITIAL_NUMBER = { val: 10 };

export default function App() {
  const [number, setNumber] = useState(INITIAL_NUMBER);
  // 基于初始常量拷贝,而不是基于当前状态拷贝
  const numberAssign = Object.assign({}, INITIAL_NUMBER);
  const numberSpread = { ...INITIAL_NUMBER };
  const numberJSON = JSON.parse(JSON.stringify(INITIAL_NUMBER));
  
  const clicked = () => {
    setNumber({ val: number.val + 1 });
  };

  return (
    <div className="App">
      <button onClick={clicked}>Inc</button>
      <p>{number.val}</p>
      <p>{numberAssign.val}</p>
      <p>{numberSpread.val}</p>
      <p>{numberJSON.val}</p>
    </div>
  );
}

方案2:初始值为动态生成时,用useRef存储

如果初始值需要在组件渲染时动态生成(比如从props取值、计算得到),用useRef存储初始值,ref的值不会随组件重渲染更新:

import { useState, useRef } from "react";
import "./styles.css";

export default function App(props) {
  // 用useRef存初始值,只会在组件首次挂载时初始化一次
  const initialNumberRef = useRef({ val: props.initialVal || 10 });
  const [number, setNumber] = useState(initialNumberRef.current);
  
  const numberAssign = Object.assign({}, initialNumberRef.current);
  const numberSpread = { ...initialNumberRef.current };
  const numberJSON = JSON.parse(JSON.stringify(initialNumberRef.current));
  
  const clicked = () => {
    setNumber({ val: number.val + 1 });
  };

  return (
    <div className="App">
      <button onClick={clicked}>Inc</button>
      <p>{number.val}</p>
      <p>{numberAssign.val}</p>
      <p>{numberSpread.val}</p>
      <p>{numberJSON.val}</p>
    </div>
  );
}

内容的提问来源于stack exchange,提问作者Zbyněk Juřica

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 01:45:03