React ref的使用示例
写了一段时间的 react,99%都在写 state、prop、usestate、useeffect,对 ref 特别不熟悉,前几天做一个需求,想用 ref 实现父组件捞子组件的某个状态值,结果失败了,特此整理一下 ref 相关内容。
什么是 ref
官网介绍:
在典型的 react 数据流中,props 是父组件与子组件交互的唯一方式。要修改一个子组件,你需要使用新的 props 来重新渲染它。但是,在某些情况下,你需要在典型数据流之外强制修改子组件。被修改的子组件可能是一个 react 组件的实例,也可能是一个 dom 元素。对于这两种情况,react 都提供了解决办法,即使用 ref 来获取 dom 或组件实例。
如何使用 ref
放在 dom 元素上
这是 ref 最直接的用法
打印看一下 ref 是啥
可以看出,ref.current 拿到了 dom 元素,所以我们可以实现 dom 元素本身的一些功能,如 input 的聚焦:
官网还提供了一种 ref 回调的形式:
放在类组件上
其实组件跟原生 dom 差不多,也是拥有自己的 ui、一些功能的某种元素,所以将 ref 放在组件上,也可以获取到该组件的示例。
那既然可以获取到子组件的实例,我们就可以操作子组件了,比如文章最开始说,我想在父组件里去捞子组件的某些状态值。
既然能拿值,我也能拿函数去修改子组件
当然这个例子并不恰当,父组件想更改子组件的状态的话,应该把状态提升到父组件中,然后作为子组件的props传递进去。
主要是 ref 提供一种方式去绕过 props 来实现父子组件通信。
放在函数组件上
这是我文章开头写需求时犯的错,ref 不能放在函数组件上,因为函数组件没有实例。
那函数组件就不能使用 ref 了吗,那肯定不是哈哈。我们可以使用 forwardref 包装函数组件。
这里贴一下官网的 tip:
那既然函数组件也可以使用 ref 的话,我们用函数组件实现一下父组件捞子组件的数据,不过可以看出,使用 forwardref 包裹后,ref 还是得挂载到 dom 或者类组件上,如果我只想挂载数据还需要搭配 useimperativehandle。
至此完成了做需求时留下的问题 ✅
总结
最后还是需要强调一下,父组件获取子组件状态的场景,一般还是状态提升 + 回调来通信,需求最终也是使用这种方式来实现的,最开始之所以想用 ref,是觉得状态提升后,子组件变化了会引起父组件的重新渲染,但是我只想拿数据而不引起渲染。
跟师傅说了一下我写需求时的想法,师傅见解如下:
- 优先考虑状态提升
- 有性能问题的话,考虑状态提升 + memo
- 不想给多个组件加 memo 的话,就要考虑引入 redux/mobx 了
- 如果引入 redux/mobx 是一种成本的话,那 ref 也不是不可以哈哈哈
以上就是react ref的使用详解的详细内容,更多关于react ref的使用的资料请关注其它相关文章!