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

React.useState替代方案:对象式useState的实现及问题咨询

objectUseState数组操作兼容优化方案

你当前实现的核心问题是只对顶层对象的属性赋值做了拦截,没有递归处理嵌套的引用类型(比如数组、子对象),所以数组的push等变异操作无法被拦截触发更新,可通过以下思路优化:

  • 递归代理所有嵌套引用类型:在Proxy的get拦截逻辑中增加判断,只要获取到的属性值是对象/数组类型,就给它也套上一层相同的Proxy再返回,保证嵌套层级的所有修改操作都能被拦截到。
  • 适配数组变异方法:数组的push、pop、splice等变异方法本质最终都会触发数组元素或length属性的set操作,只要你完成了数组的Proxy包装,这些操作天然就能被拦截到触发更新;如果存在特殊场景漏触发的情况,可以专门在get拦截中对数组的变异方法做包装,执行完原方法后手动触发一次状态更新即可。
  • 集成Immer简化不可变更新:你可以直接在状态更新逻辑中引入Immer的produce方法,不需要自己手动处理深拷贝逻辑,所有对代理对象的修改都会被Immer转化为符合React要求的不可变状态更新,天然支持数组的所有操作,还能保证未修改属性的引用稳定,避免useEffect等依赖项的意外触发。

以下是精简实现示例:

import { produce } from 'immer';
import { useState, useMemo } from 'react';

function objectUseState(initialState) {
  const [state, setState] = useState(initialState);

  const proxy = useMemo(() => {
    const createProxy = (target) => {
      return new Proxy(target, {
        set(obj, prop, value) {
          setState(prev => produce(prev, draft => {
            draft[prop] = value;
          }));
          return true;
        },
        get(obj, prop) {
          const value = obj[prop];
          // 嵌套对象/数组继续做代理包装
          if (typeof value === 'object' && value !== null) {
            return createProxy(value);
          }
          return value;
        }
      });
    };
    return createProxy(state);
  }, [state]);

  return proxy;
}

使用该实现后,数组的push等操作可正常触发更新,示例如下:

const state = objectUseState({
  list: []
});

// 点击后会往list新增元素并触发视图更新
return <Text onPress={() => state.list.push('新元素')}>{state.list.length}</Text>

内容的提问来源于stack exchange,提问作者Alen.Toma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:30:03