vue3 reactive 对比 react useState 以及 ramda 和 lodash 的取舍问题

原创
07/25 12:24
阅读数 507

vue3 的 reactive  和 react的useState有着根本上的不同

const { ref, reactive, watch } = require("vue");

let s1 = reactive({ x: 0 });
let s2 = reactive({ x: 0 });
let s3 = s2;

watch([s1], (newS1) => {
  console.log("watch s1", newS1);
});
watch([s2], (newS2) => {
  console.log("watch s2", newS2);
});
watch([s3], (newS3) => {
  console.log("watch s3", newS3);
});
setTimeout(() => {
  s1.x = 2;
  s2 = {
    x: 111,
  };
  s3.x = 444;
}, 1000);

上述代码的输出如下,  s1的watch生效了, 而s3的修改触发了两次watch

单独设置s2并不会出现任何输出

setTimeout(() => {
  s2 = {
    x: 111,
  };
}, 1000);

 

 

对比react

采用的比较方式是===比较, 所以在原对象上的修改会被忽视, 而ramda每次总是返回新对象的特点正好契合react的方式

import React, {
  useState,
  useRef,
  useLayoutEffect,
  useCallback,
  useEffect,
  useMemo,
} from "react";

export default () => {
  const initState = { x: 0 };
  const [a, setA] = useState(initState);
  const change = () => {
    // 这样设置不会生效
    // a.x = 3;
    // setA(a)

    setA({ x: 3 });
  };
  return (
    <div>
      a:{a.x} <button onClick={change}>change</button>
    </div>
  );
};

 

 

ramda

const R = require("ramda");
let obj = { x: 0 };
let newObj = R.assoc('x', 3, obj);
// { x: 0 } { x: 3 } false
console.log(obj, newObj, obj === newObj);

lodash

const _ = require("lodash");
let obj = { x: 0 };
let newObj = _.set(obj, "x", 3);
// { x: 3 } { x: 3 } true
console.log(obj, newObj, obj === newObj);

 

其本质上的不同就在于一个总是返回新对象, 虽然对象中的值是浅拷贝的, 一个返回的是原始对象, 是在源对象上做的修改

当然在vue中也能使用ramda, 但是需要注意不要直接修改reactive的引用,而是每次修改其属性值

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部