在React中模拟vue3来简化变量操作和视图更新

76 阅读1分钟

一直在用vue开发 忽然接到react项目的任务 用了两三天学习了下react 在写的时候感觉定义状态和去驱动识图更新没有vue3方便 就有给自己写了个代理hook 瞬间又舒服了 哈哈哈

// React代码
import { useState, useMemo } from 'react';

function useCounter(initialValue) {
  const [count, setCount] = useState(initialValue);

  const countProxy = useMemo(() => {
    return new Proxy({ value: count }, {
      set(target, key, value) {
        target[key] = value;
        setCount(target.value); // 手动更新状态
        return true;
      },
      get(target, key) {
        return target[key];
      },
    });
  }, [count]);

  const increment = () => {
    countProxy.value++;
  };

  const decrement = () => {
    countProxy.value--;
  };

  const reset = () => {
    countProxy.value = initialValue;
  };

  const doubledCount = useMemo(() => countProxy.value * 2, [countProxy]);

  return {
    count: countProxy.value,
    increment,
    decrement,
    reset,
    doubledCount,
  };
}

// Vue 3代码
import { ref, computed } from 'vue';

function useCounter(initialValue) {
  const count = ref(initialValue);

  const countProxy = new Proxy({ value: count.value }, {
    set(target, key, value) {
      target[key] = value;
      count.value = target.value; // 手动更新状态
      return true;
    },
    get(target, key) {
      return target[key];
    },
  });

  const increment = () => {
    countProxy.value++;
  };

  const decrement = () => {
    countProxy.value--;
  };

  const reset = () => {
    countProxy.value = initialValue;
  };

  const doubledCount = computed(() => countProxy.value * 2);

  return {
    count: countProxy.value,
    increment,
    decrement,
    reset,
    doubledCount,
  };
}

在以上代码中,我们使用了Proxy来创建一个代理对象countProxy,它包含了一个名为value的属性,它的值始终与原始状态值count同步。我们通过set方法和get方法来拦截对countProxy对象的赋值和取值操作。在set方法中,我们首先更新countProxyvalue属性,然后手动更新React或Vue 3的状态值,以确保视图会更新。

incrementdecrementresetdoubledCount计算属性中,我们可以直接对countProxy.value进行操作,因为它会自动触发代理对象中的set方法。最终,我们从countProxy对象中返回value属性,以便React或Vue 3可以使用它来更新视图。