- 主题:对比 vue,reactjs 就是个笑话!
干活儿需要的是API给一个promise,不是限制死API的实现方式
知道实现细节固然好,但对于干活儿来讲没有必要
好的API就好在它把活儿干了你啥都没感觉到
如果闹到必须知道细节,那这框架一般就没法用了
【 在 beep (菜M.喵星耗子) 的大作中提到: 】
: useState useEffect useMemo 的原理非常重要,不是实现细节。不懂具体怎么实现的,只背api,分分钟掉到沟里,基本没法干活
--
FROM 111.163.120.*
没研究过,不了解
【 在 littleSram (littleSram) 的大作中提到: 】
: 学习了
: ng2和react比较呢?
--
FROM 122.57.163.*
我就说我这个例子不好,果然带来了一些误会。
首先,useEffect 产生的是 side effect,通过某些 state 值从获取数据。那么正常情况下,你所使用的 value 值应该是从外部的 counter 来的,而不可能是在 setCounter 中再取一遍当前值。这里面的逻辑是,当产生外部作用的时候,控件的状态是 A,等异步执行完之后,控件的状态已经变成 B 了,这时再用 A 计算出来的结果去更新 B 状态,那么这个操作很大概率是错的。
其次,我的例子也是偷懒了,写成
const value = ref(...) vs const [value, setValue] = useState(...)
const step = ... vs const [step, setStep] = ...
可能更合适一些。
另外,按照 react 的设计,如果用 counter 的数据结构,使用 useReducer 更合理一些。这种情况下,具体用原来 value 还是增加后的 value,取决于 reducer/dispatch 怎么设计的。而 vue 的话,如果想用原本的 value 值,你会发现没那么容易了。
最后,react 里由于所有的函数都是完全正常的 js,多个 useEffect 是按照顺序执行的。在 vue 里面,watcher 的执行顺序就有有魔法了,没记错的话,watch 的是 computed 的话,那么会在 data/reactive wachters 运行完成之后才执行。
useState 里面的 setter,如果用函数形式的话,非异步的执行是合理的。如果是复杂数据结构的话,可以根据 useReducer 和多次 dispatch 来控制想要的执行结果。还是老话,每一步都是 newState = reduce(oldState, action),没有意外也很容易写 unittest。
【 在 beep (菜M.喵星耗子) 的大作中提到: 】
: @eGust 试了一下,有意思。
: const [counter, setCounter] = useState({ value: 1, step: 1 })
: useEffect(() => {
: ...................
--
FROM 122.57.163.*
在前端框架的数据响应化这个领域,没有你想的这么理想。无论是vue/mobx的proxy api,还是react的class组件api,hooks api,还是ng的rxjs、普通模式、onPush模式,都需要用户对原理有了解。
了解原理,就不出bug。不了解原理,就得死背几种甚至几十种边界情况的规范,而且永远有新发现的边界情况。相对来说vue这种的边界情况还是好的,主要就是不能过早dereference丢失引用。
【 在 tgfbeta (右旋肉碱) 的大作中提到: 】
: 干活儿需要的是API给一个promise,不是限制死API的实现方式
: 知道实现细节固然好,但对于干活儿来讲没有必要
: 好的API就好在它把活儿干了你啥都没感觉到
: ...................
--
FROM 123.120.168.*
【 在 eGust (十年) 的大作中提到: 】
: 标 题: Re: 对比 vue,reactjs 就是个笑话!
: 发信站: 水木社区 (Thu Jul 1 06:07:35 2021), 站内
:
: 我就说我这个例子不好,果然带来了一些误会。
:
: 首先,useEffect 产生的是 side effect,通过某些 state 值从获取数据。那么正常情况下,你所使用的 value 值应该是从外部的 counter 来的,而不可能是在 setCounter 中再取一遍当前值。这里面的逻辑是,当产生外部作用的时候,控件的状态是 A,等异步执行完之后,控件的状态已经变成 B 了,这时再用 A 计算出来的结果去更新 B 状态,那么这个操作很大概率是错的。
明白你的意思了,你是说,前面例子中,如果用户需要从当前的外部counter取值,也应该能做到?vue也可以啊,watch(someRef, (v, oldV) => ... ) 这里就可以取到someRef的当前值。(顺便还附赠可以一起取到旧值。react hooks下useEffect里是取不到旧值的,官方也没有相关api,只能用户自己通过useRef来hack)
watch(aRef, (v) => aRef.value = v+1)
useEffect(() => setA(a+1))
这两个行为一致,都是多次运行的话取到同样的初始值,就是定义变更函数时就固定了a或者v的值
watch(aRef, () => aRef.value = aRef.value+1)
useEffect(() => setA((v) => v+1))
这两个行为也一致,是函数真实运行的时候才去取aRef、v的值。
:
: 其次,我的例子也是偷懒了,写成
: const value = ref(...) vs const [value, setValue] = useState(...)
: const step = ... vs const [step, setStep] = ...
: 可能更合适一些。
:
: 另外,按照 react 的设计,如果用 counter 的数据结构,使用 useReducer 更合理一些。这种情况下,具体用原来 value 还是增加后的 value,取决于 reducer/dispatch 怎么设计的。而 vue 的话,如果想用原本的 value 值,你会发现没那么容易了。
如上,也很容易
:
: 最后,react 里由于所有的函数都是完全正常的 js,多个 useEffect 是按照顺序执行的。在 vue 里面,watcher 的执行顺序就有有魔法了,没记错的话,watch 的是 computed 的话,那么会在 data/reactive wachters 运行完成之后才执行。
这个我没听说过,之后可以试试看。不过react官方没有提供computed的对应物,还得自己先实现一个...
:
: useState 里面的 setter,如果用函数形式的话,非异步的执行是合理的。如果是复杂数据结构的话,可以根据 useReducer 和多次 dispatch 来控制想要的执行结果。还是老话,每一步都是 newState = reduce(oldState, action),没有意外也很容易写 unittest。
:
useReducer就是套壳的useState嘛,没啥区别,都是用户可以根据需求,用上面两种形式实现两种不同行为
: 【 在 beep (菜M.喵星耗子) 的大作中提到: 】
: : @eGust 试了一下,有意思。
: : const [counter, setCounter] = useState({ value: 1, step: 1 })
: : useEffect(() => {
: : ...................
:
: --
:
: ※ 来源:·水木社区 mysmth.net·[FROM: 122.57.163.*]
--
FROM 123.120.168.*
vue模板和style区域还是把html和CSS有效分开了
【 在 tgfbeta 的大作中提到: 】
: 在倒退方面,vue和react半斤八两,都是用js替代html/css分离的设计。【 在 hgoldfish (老鱼) 的大作中提到: 】: 最近有调查说 vue 在国内的使用率不断降低,reactjs 不断提升。对此本青表示痛心疾首!这是一种历史的倒退!: 想当初 java 程序员费了九牛二虎之力,从 html 和 java 代码混合的 jsp 进化到了 struts,现在又进化到 spring boot,终于做到做业务逻辑和页面设计分开,方便设计师和程序员分工合作。从此前后端分离,终于发展出 js 前端社区。php, python, ruby 等社区也发展出类似的:
http://blog.itpub.net/69981092/viewspace-2710742/: ...................--FROM 111.166.5.*
来自 M2003J15SC
--
FROM 221.217.130.*
专职前端生产力都低下
【 在 shaolin 的大作中提到: 】
: 说React不如Vue的,基本都不是 专职 写前端的。就跟跑步一样,担心别人膝盖不好的,都是不跑步的人瞎操心。【 在 hgoldfish (老鱼) 的大作中提到: 】: 最近有调查说 vue 在国内的使用率不断降低,reactjs 不断提升。对此本青表示痛心疾首!这是一种历史的倒退!: 想当初 java 程序员费了九牛二虎之力,从 html 和 java 代码混合的 jsp 进化到了 struts,现在又进化到 spring boot,终于做到做业务逻辑和页面设计分开,方便设计师和程序员分工合作。从此前后端分离,终于发展出 js 前端社区。php, python, ruby 等社区也发展出类似的:
http://blog.itpub.net/69981092/viewspace-2710742/: ...................--FROM 220.181.41.*
来自 M2003J15SC
--
FROM 221.217.130.*
哈哈
【 在 shaolin 的大作中提到: 】
: 要吃饭。如果现在还是jq时代,人均还是六七千的工资。。让我我也把这东西搞复杂。【 在 chaobill (若我离去,后会无期) 的大作中提到: 】: 我想起那句话, java 善于解决 java 发明的问题: 要切图仔理解这些高深名词,真是太难了: 问题来了,为什么前端要搞那么复杂: ...................--FROM 220.181.41.*
来自 M2003J15SC
--
FROM 221.217.130.*
你还是没理解我的意思,这么举例吧:有 props P,computed C,data D 三个状态,有两个分别监听 P 和 C。C 依赖于 P,当 P 变化的时候 C 也有可能产生变化。
// w1
watch(P, () => {
D = f1(P, D); // D: d1 -> d2
})
// w2
watch(C, () => {
D = await f2(D, ...);
})
在 w1 里面,D 的值发生了变化 d1 -> d2,而在 w2 触发时,由于 D 的值已经变化了,想取得原始值 d1 是非常困难的。而取得 d1 的值是完全合理的选择,因为在 C 的状态发生变化的时候,D 的值还是 d1。
换成等价的 react 操作
// e1
useEffect(() => {
setD(f1(D, P)) // D: d1 -> d2
}, [P])
// e2
useEffect(async () => {
setD(await f2(D, P))
}, [P, ...]) // 相当于 C = computed(P, ...)
在 e2 发生的时候,D 的值仍然是 d1,进行 setD(async (d2) => f2(d2, P)) 这种操作是非法的。而对于
d3 = await f2(D, P) // D === d1
setD((d2) => d3)
这种操作,是在用基于 D === d1 的状态求出来的结果 d3,去更新 D === d2 的状态,很可能并不是想要的结果,而是引入了一个 bug。那么解决的办法就是 reducer
D = reduce({ D: d2 }: State, { P, D: d3, oldD: d1 }: Action)
【 在 beep (菜M.喵星耗子) 的大作中提到: 】
: 明白你的意思了,你是说,前面例子中,如果用户需要从当前的外部counter取值,也应该能做到?vue也可以啊,watch(someRef, (v, oldV) => ... ) 这里就可以取到someRef的当前值。(顺便还附赠可以一起取到旧值。react hooks下useEffect里是取不到旧值的,官方也没有相关a
: watch(aRef, (v) => aRef.value = v+1)
: useEffect(() => setA(a+1))
: ...................
--
修改:eGust FROM 101.98.83.*
FROM 101.98.83.*
为啥调试麻烦?是 pure function 是 function 的子集,immutable 是变量的子集,为啥调试超集没问题,子集反倒出问题了?
【 在 chaobill (若我离去,后会无期) 的大作中提到: 】
: fp 的一大问题是调试麻烦
--
FROM 101.98.83.*