1. ref是什么?
  2. ref是组件的特殊属性,组件被渲染后,指向组件的一个引用。可以通过组件的ref属性,来获取真实的组件。因为,组件并不是真正的DOM节点,而是存在于内存中的一种数据结构,
    称为虚拟的DOM,只有当它真正的插入文档之后,才变为真正的DOM节点。根据React的设计,所以的DOM变动都发生在虚拟DOM上,然后再将实际的部分反映到真实的DOM上--这就是 DOM DIff,它可以提高页面性能。
  3.  
  4. 如何使用ref呢?
  5.  
  6. ref属性的定义是在使用组件的部分,而组件的方法之类的都是在定义组件的里面就有的。render方法被调用的时候,组件就会被渲染。渲染完成之后,就可以获取这个组件实例啦,因而就可以调用组件实例里的方法或者变量啦。

React的ref有3种用法:

1. 字符串(已废弃)
2. 回调函数
3. React.createRef() (React16.3提供)

1. 字符串

最早的ref用法。

1.dom节点上使用,通过this.refs[refName]来引用真实的dom节点

  1. <input ref="inputRef" /> //this.refs['inputRef']来访问

2.类组件上使用,通过this.refs[refName]来引用组件的实例

  1. <CustomInput ref="comRef" /> //this.refs['comRef']来访问

2. 回调函数

回调函数就是在dom节点或组件上挂载函数,函数的入参是dom节点或组件实例,达到的效果与字符串形式是一样的,
都是获取其引用。

回调函数的触发时机:。

1. 组件渲染后,即componentDidMount后
2. 组件卸载后,即componentWillMount后,此时,入参为null
3. ref改变后

1.dom节点上使用回调函数

  1. <input ref={(input) => {this.textInput = input;}} type="text" />

2.类组件上使用使用回调函数

  1. <CustomInput ref={(input) => {this.textInput = input;}} />

3.可用通过props跨级传递的方式来获取子孙级dom节点或组件实例

下面是在跨两级获取到孙级别的组件内部的dom节点

  1. function CustomTextInput(props) {
  2. return (
  3. <div>
  4. <input ref={props.inputRef} />
  5. </div>
  6. );
  7. }
  8. function Parent(props) {
  9. return (
  10. <div>
  11. My input: <CustomTextInput inputRef={props.inputRef} />
  12. </div>
  13. );
  14. }
  15. class Grandparent extends React.Component {
  16. render() {
  17. return (
  18. <Parent
  19. inputRef={el => this.inputElement = el}
  20. \/>
  21. );
  22. }
  23. }

3.React.createRef()

在React 16.3版本后,使用此方法来创建ref。将其赋值给一个变量,通过ref挂载在dom节点或组件上,该ref的current属性
将能拿到dom节点或组件的实例
例如

  1. class Child extends React.Component{
  2. constructor(props){
  3. super(props);
  4. this.myRef=React.createRef();
  5. }
  6. componentDidMount(){
  7. console.log(this.myRef.current);
  8. }
  9. render(){
  10. return <input ref={this.myRef}/>
  11. }
  12. }

4.React.forwardRef

同样是React 16.3版本后提供的,可以用来创建子组件,以传递ref。
例如:

  1. //子组件(通过forwardRef方法创建)
  2. const Child=React.forwardRef((props,ref)=>(
  3. <input ref={ref} />
  4. ));
  5.  
  6. //父组件
  7. class Father extends React.Component{
  8. constructor(props){
  9. super(props);
  10. this.myRef=React.createRef();
  11. }
  12. componentDidMount(){
  13. console.log(this.myRef.current);
  14. }
  15. render(){
  16. return <Child ref={this.myRef}/>
  17. }
  18. }

子组件通过React.forwardRef来创建,可以将ref传递到内部的节点或组件,进而实现跨层级的引用。

forwardRef在高阶组件中可以获取到原始组件的实例

例如:

  1. //生成高阶组件
  2. const logProps=logProps(Child);
  3.  
  4. //调用高阶组件
  5. class Father extends React.Component{
  6. constructor(props){
  7. super(props);
  8. this.myRef=React.createRef();
  9. }
  10. componentDidMount(){
  11. console.log(this.myRef.current);
  12. }
  13. render(){
  14. return <LogProps ref={this.myRef}/>
  15. }
  16. }
  17.  
  18. //HOC
  19. function logProps(Component) {
  20. class LogProps extends React.Component {
  21. componentDidUpdate(prevProps) {
  22. console.log('old props:', prevProps);
  23. console.log('new props:', this.props);
  24. }
  25.  
  26. render() {
  27. const {forwardedRef, ...rest} = this.props;
  28.  
  29. // Assign the custom prop "forwardedRef" as a ref
  30. return <Component ref={forwardedRef} {...rest} />;
  31. }
  32. }
  33.  
  34. // Note the second param "ref" provided by React.forwardRef.
  35. // We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
  36. // And it can then be attached to the Component.
  37. return React.forwardRef((props, ref) => {
  38. return <LogProps {...props} forwardedRef={ref} />;
  39. });
  40. }
  1. //生成高阶组件
  2. const logProps=logProps(Child);
  3.  
  4. //调用高阶组件
  5. class Father extends React.Component{
  6. constructor(props){
  7. super(props);
  8. this.myRef=React.createRef();
  9. }
  10. componentDidMount(){
  11. console.log(this.myRef.current);
  12. }
  13. render(){
  14. return <LogProps ref={this.myRef}/>
  15. }
  16. }
  17.  
  18. //HOC
  19. function logProps(Component) {
  20. class LogProps extends React.Component {
  21. componentDidUpdate(prevProps) {
  22. console.log('old props:', prevProps);
  23. console.log('new props:', this.props);
  24. }
  25.  
  26. render() {
  27. const {forwardedRef, ...rest} = this.props;
  28.  
  29. // Assign the custom prop "forwardedRef" as a ref
  30. return <Component ref={forwardedRef} {...rest} />;
  31. }
  32. }
  33.  
  34. // Note the second param "ref" provided by React.forwardRef.
  35. // We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
  36. // And it can then be attached to the Component.
  37. return React.forwardRef((props, ref) => {
  38. return <LogProps {...props} forwardedRef={ref} />;
  39. });
  40. }

注意:
1. ref在函数式组件上不可使用,函数式组件无实例,但是其内部的dom节点和类组件可以使用
2. 可以通过ReactDOM.findDOMNode(),入参是一个组件或dom节点,返回值的组件对应的dom根节点或dom节点本身
   通过refs获取到组件实例后,可以通过此方法来获取其对应的dom节点
3. React的render函数返回的是vDom(虚拟dom)

参考:https://blog.csdn.net/liangklfang/article/details/72858295
         https://blog.csdn.net/liwusen/article/details/80009968

React Native中ref的用法(通过组件的ref属性,来获取真实的组件)的更多相关文章

  1. react native中state和ref的使用

    react native中state和ref的使用 因props是只读的,页面中需要交互的情况我们就需要用到state. 一.如何使用state 1:初始化state 第一种方式: construct ...

  2. React Native中加载指示器组件ActivityIndicator使用方法

    这里讲一下React Native中的一个组件——ActivityIndicator,这是一个加载指示器,俗称菊花,很常见的,效果如下所示: 可以看到图中有两个加载指示器,一大一小,这是尺寸不是我设置 ...

  3. React Native中组件的props和state

    一.组件的属性(props)和状态(state) 1.属性(props) 它是组件的不可变属性(组件自己不可以自己修改props). 组件自身定义了一组props作为对外提供的接口,展示一个组件时只需 ...

  4. [转] 「指尖上的魔法」 - 谈谈 React Native 中的手势

    http://gold.xitu.io/entry/55fa202960b28497519db23f React-Native是一款由Facebook开发并开源的框架,主要卖点是使用JavaScrip ...

  5. 在 React Native 中使用 Redux 架构

    前言 Redux 架构是 Flux 架构的一个变形,相对于 Flux,Redux 的复杂性相对较低,而且最为巧妙的是 React 应用可以看成由一个根组件连接着许多大大小小的组件的应用,Redux 也 ...

  6. [转] 在React Native中使用ART

    http://bbs.reactnative.cn/topic/306/%E5%9C%A8react-native%E4%B8%AD%E4%BD%BF%E7%94%A8art 前半个月捣腾了一下Rea ...

  7. react native中使用echarts

    开发平台:mac pro node版本:v8.11.2 npm版本:6.4.1 react-native版本:0.57.8 native-echarts版本:^0.5.0 目标平台:android端收 ...

  8. 在React Native中,使用fetch网络请求 实现get 和 post

    //在React Native中,使用fetch实现网络请求 /* fetch 是一个封装程度更高的网络API, 使用了Promise * Promise 是异步编程的一种解决方案 * Promise ...

  9. 《React Native 精解与实战》书籍连载「React Native 中的生命周期」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

随机推荐

  1. ABC065D Built[最小生成树]

    这题和某道最短路题神似.对于任意点对,将他们连边,不如将他们分别沿$x,y$轴方向上点按顺序连起来,这样不仅可能多连通一些点,也花费更低,所以按照最短路那题的连边方式跑一个kruskal就行了. #i ...

  2. Eclipse指定jdk启动

    在eclipse.ini文件中加入这一句话: -vm D:/Java/jdk/jdk1.8/jre/bin/server/jvm.dll

  3. mysql中source提高导入数据速率的方法

    示例: 第一步: 第二步: 使用 source 导入你所需要导入的文件 第三步: 在导入的数据停止后,输入  commit; 这样数据就算是导入完成了.

  4. python中ord()函数,chr()函数,unichr()函数

    ord()函数,chr()函数,unichr()函数 chr()函数用一个范围在range(256)内的(就是0-255)整数作参数,返回一个对应的字符.unichr()跟它一样,只不过返回的是Uni ...

  5. 6 RESTful规范

    https://www.cnblogs.com/alice-bj/p/9258121.html 1.什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representat ...

  6. 题解 比赛 match

    比赛 match Description 有 N 支队伍打比赛.已知有如下条件: • 每支队伍恰好打了 4 场比赛 • 对于一场比赛,如果是平局,双方各得 1 分:否则胜者得 3 分,负者不得分 给定 ...

  7. 【Python之路】特别篇--Celery

    Celery介绍和基本使用 Celery 是一个分布式异步消息队列,通过它可以轻松的实现任务的异步处理 举几个实例场景中可用的例子: 你想对100台机器执行一条批量命令,可能会花很长时间 ,但你不想让 ...

  8. JQuery操作DOM(8)

    一.jQuery操作样式 1.设置和获取样式 /* 单个样式 */ $(selector).css(属性,值): /* 多个样式 */ $(selector).css({属性:值,属性:值}); /* ...

  9. 记一次newApiHadoopRdd查询数据不一致问题

    现象: +----------+-------+--------+-----+-----+-----+----+----+------+---------+-------+--------+----- ...

  10. css 元素的竖向百分比设定是相对于容器的高度吗?

    结论是,如果是height的话,是相对于容器高度,如果是padding-height,margin-height则是相对于容器的宽度. 举例说明: <!DOCTYPE html> < ...