怎么理解 Vue 和 React 都有的 ref 这个概念?为什么要这样设计?

2023-03-14 16:32:01 +08:00
 WangLiCha

之前我是做 WPF 的,在 WPF 里的控件(对应 Web 前端的组件)都有一个 Name 属性,在后台代码里可以直接通过这个 Name 属性获取控件的实例,以及根据控件的实例属性获取他全部子元素的实例,然后进行一些操作。

但是接触到 Web 前端框架过后,发现无论是 Vue 还是 React 都不能像 WPF 一样方便获取组件的实例,而是需要一个不是很直观的 ref 来辅助获取,而且即使获取到了,在通过代码获取子组件也很困难,比如 Ant Design 的 Tabs 控件,除非为所有的 items 的 children 手动添加 ref ,否则是没法获取每个 children 的实例的。

所以现在很疑惑,应该怎么理解 Vue 和 React 都有的 ref 这个概念?为什么要这样设计呢?

3849 次点击
所在节点    程序员
26 条回复
xieqiqiang00
2023-03-14 16:43:31 +08:00
组件有状态
TWorldIsNButThis
2023-03-14 16:44:09 +08:00
react hook 的 ref 类比是 java 的 threadlocal ,更准确的说是未来的 scopedValue
绑定到组件实例只是一个特殊用法

react 的思维模型是声明式+单向数据流,渲染结果是 state 的映射,脱离 state 直接操作组件本体是 anti-pattern
xieqiqiang00
2023-03-14 16:47:11 +08:00
有些组件是受控组件,由它的父组件的状态来管理,这时候要是直接被别的组件随便改了就出现意料之外的情况了。而且组件是否刷新也要根据状态来定,并且有明确的层级关系才方便确定哪些组件需要刷新。并且组件也不是一直存在的,随时都会创建和销毁
wanguorui123
2023-03-14 16:50:31 +08:00
因为有些特殊功能需要通过 MVP 模式实现
moen
2023-03-14 17:10:16 +08:00
可是 WPF 下直接操作组件本身就是 anti-pattern
wu67
2023-03-14 17:15:48 +08:00
react 我玩得不多.
vue 的话, 主要是配合一些三方库的时候, 尤其是需要对 dom 进行操作时(例如部分视频播放器的初始化), 会很有用. 避免了你去手动操作 dom.
journalistFromHK
2023-03-14 17:20:01 +08:00
vue react 这种的最后都会把页面弄成一个超大的 js…加入 ref 才方便找到元素吧 我猜
gam2046
2023-03-14 17:23:07 +08:00
WPF 的 Name 就相当于 DOM id ,你为每个组件指定了 id,随时都可以 document.getElementById ,只是前端不要求你强制设置 id 属性而已。

但是你啥都通过 id 一把梭上去改了,就不需要 vue 这样的框架了
summerLast
2023-03-14 17:30:36 +08:00
template 和 js 是两套写法,通过 ref 写法 ,只是一个桥
sparklee
2023-03-14 17:31:40 +08:00
就是为虚拟 dom 指定与页面 dom 之间的关联 key, 我的理解
WangLiCha
2023-03-14 17:55:39 +08:00
@moen 也不能说操作,不过确实少数特殊场景下确实直接操作或者读取控件是比较方便的,WPF 可以这样做(虽然我知道并不推荐),但是前端框架对此的限制感觉要严格得多,想知道这是为什么
joesonw
2023-03-14 20:44:46 +08:00
@WangLiCha 谁都能随便改来改去,人多了这项目怎么写,看 render function 就没意义了,render 出来别人也可能改掉了。mvvm 的概念就是 view = f(view model)。view 的改变要通过改变 viewModel 来触发 f 重新渲染。
anonymous2351d00
2023-03-14 21:27:21 +08:00
我粗略的理解
- ref = 引用
- 在数据层面 ref 大概就是指针?指向内存
- 在视图层面 ref 大概也是指针?指向视图元素所对应的 object/类 /实体
jsun
2023-03-14 21:47:13 +08:00
现在前端框架的思想是数据驱动视图,要根据数据进行渲染,ref 更多是为了一些特殊场景准备的。
Rocketer
2023-03-14 22:03:26 +08:00
angular 也有 ref ,但无论哪个前端框架,直接操作 ref 都是不推荐的。理想状态下所有操作都应该通过属性或者状态管理实现,除非实在不行。

类似的还有 formcontrol ,实在是恶心至极
daysv
2023-03-14 22:37:17 +08:00
因为 ocaml 有 ref
mingwiki
2023-03-14 22:38:16 +08:00
有一个原生的 ref 叫 weakRef 是为了防止被垃圾回收的 我觉得是一个作用
xiangyuecn
2023-03-14 22:46:05 +08:00
有了 ref ,就能直接访问到目标实例的方法、属性,大幅减少代码量,简单易懂🐶
IvanLi127
2023-03-14 23:29:42 +08:00
1. 为了写高性能代码
2. 为了操作更底层的对象
cyitao
2023-03-14 23:50:58 +08:00
你可以通过 window.divId 获取到 id 为 divId 的 dom 实例。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/923945

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX