我咋觉得react也一样呢?复刻一下这个例子:
const [{ value, step }, setCounter] = useState(counter);
useEffect(() => {
console.debug("watcher A", { ...counter });
setCounter(old => ({ value: old.value + old.step, step: old.step })) // 1
}, [step]);
useEffect(() => {
console.debug("watcher B", { ...counter });
setCounter(old => ({ value: old.value + old.step, step: old.step })) // 2
}, [step]);
跑的时候 1 和 2 两个 setCounter 也是顺序运行的,它们各自取到的 old.value 也不一样吧?
我个人理解,useState useEffect 本质就是为了造成纯组件函数的“假象”,把生存周期是跨越多次渲染而一直存在的 state 变量、effect 函数,都存到了用户看不见的闭包里,因为 react 函数组件只有一层 render 函数,正常来看的话没有造闭包的地儿:
...; // state 和 effect 真实创建于框架代码里,也就是组件 render 函数体之外
function Component () {
...; // render 通过 useState useEffect 取出作用域外的闭包变量
}
而 vue 是把这种变量显式地放在 setup 函数形成的闭包里。
setup() {
...; // 构造跨多次渲染的闭包变量
return () => {
// render 直接通过原生js作用域机制获取外面的闭包变量
}
}
所以本质都是闭包变量,只是闭包的位置不同而已吧?
除非说 react 内部在上述同一批次内多次调用 setCount 的时候,故意都是传入初始的
count,而不是前面 setCount 修改过的 count。。。如果真是这样,我觉得反而不符合用户意图啊?
稍后有空试一下。
【 在 eGust (十年) 的大作中提到: 】
: 标 题: Re: 对比 vue,reactjs 就是个笑话!
: 发信站: 水木社区 (Wed Jun 30 16:51:15 2021), 站内
:
: 重点并不在 watch 上,declarative ui 是 model -> view 的映射。理论上只要给定了
一个确定的状态,state 也好 data 也好,都能生成一个确定的 ui。
:
: react 里面 newState = reduce(oldState, action),这是一个非常确定的状态。举一个
counter.value += Number(counter.step);
}, [step]);
【 在 eGust (十年) 的大作中提到: 】
: 标 题: Re: 对比 vue,reactjs 就是个笑话!
: 发信站: 水木社区 (Wed Jun 30 16:51:15 2021), 站内
:
: 重点并不在 watch 上,declarative ui 是 model -> view 的映射。理论上只要给定了一个确定的状态,state 也好 data 也好,都能生成一个确定的 ui。
:
: react 里面 newState = reduce(oldState, action),这是一个非常确定的状态。举一个不太恰当的例子:
: import { reactive, watch, toRef } from "vue";
:
: export const counter = reactive({
: value: 1,
: step: 1
: });
:
: const step = toRef(counter, "step");
:
: watch(step, () => {
: console.debug("watcher A", { ...counter });
: counter.value += Number(counter.step);
: });
:
: watch(step, () => {
: console.debug("watcher B", { ...counter });
: counter.value += Number(counter.step);
: });
:
: 如果 step 的值改变了:1 -> 2,那么你会看到的输出是
: watcher A { value: 1, step: 2 }
: watcher B { value: 3, step: 2 }
:
: 如果把这个实现换成 react 的话,由于 value 是从
: const [{ value, step }, setCounter] = useState(counter);
:
: 里取出来的,所以不管有几个 useEffect,调用了几次 setCounter,在所有的 effect 函数里面,value 的值都会是 1。
:
: 这个例子本身很不好,实际中的情况是,多个 watchers 监听各自的 props/computed,但它们都会根据变化来和 data 本身的值来更新 data,于是就产生了不确定性。但是一时间不太容易构造一个合适的例子,临时只能想出这个示意一下,不知道解释明白了没……
:
: 【 在 beep (菜M.喵星耗子) 的大作中提到: 】
: : 下面这一段,watcher的复杂性,和useEffect有何不同呢?useEffect如何解决“触发顺序”之类的问题呢?
:
:
: --
:
: ※ 修改:·eGust 于 Jun 30 17:00:22 2021 修改本文·[FROM: 101.98.83.*]
: ※ 来源:·水木社区 mysmth.net·[FROM: 101.98.83.*]
--
修改:eGust FROM 101.98.83.*
FROM 123.120.168.*