概述

很久之前就知道refs,感觉好神秘,恰好今天突然发现字符串形式的ref在官网不推荐使用了,于是好好总结一下ref的用法,供以后开发时参考,相信对其他人也有用。

参考资料:

Refs & DOM

Forwarding Refs

refs

在react数据流中,可以通过props,refs和Context来访问其它组件的属性,其中利用refs可以在数据流外强制修改组件实例。

需要注意的是,以前是通过给refs赋一个string,比如textInput,然后就可以通过this.refs.textInput来访问DOM节点,示例如下:

import React, { Component } from 'react';

class NoControl extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
console.log(this.refs.name);
} render() {
return(
<form onSubmit={this.handleSubmit}>
<input type="text" ref="name"/>
<button type="submit">Submit</button>
</form>
);
}
} export default NoControl;

但是官网不推荐使用这种形式使用refs了,并且这种方法在未来的版本可能会被移除。官方建议使用回调的形式代替这种使用方式。

refs的基本用法

一般说来,我们需要在constructor里面初始化一个ref,然后就能在return里面用了,示例如下:

class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}

上面的this.myRef有一个current属性,它的值取决于下面三种情况:

  1. 如果ref属性被用于html元素,那么它的值是底层DOM元素。
  2. 如果ref属性被用于自定义类组件,那么它的值是已挂载的这个自定义类组件的实例。
  3. 函数式组件没有ref属性。

另外,通过ref我们还可以调用这个自定义类组件的方法,示例如下:

import React, { Component } from 'react';

class CustomInput extends Component {
constructor(props) {
super(props);
this.handleFocus = this.handleFocus.bind(this);
this.myRef = React.createRef();
} handleFocus(e) {
this.myRef.current.focus();
}
render() {
return(
<input type="text" ref={this.myRef}/>
)
} } class NoControl extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.myRef = React.createRef();
}
handleSubmit(e) {
e.preventDefault();
this.myRef.current.handleFocus();
} render() {
return(
<form onSubmit={this.handleSubmit}>
<CustomInput ref={this.myRef}/>
<button type="submit">Submit</button>
</form>
);
}
} export default NoControl;

refs的回调用法

由于refs里面的回调函数会在组件创建的时候自动生成。所以可以利用refs的回调用法,在组件创建的时候获得这个组件的一些信息,比如获得焦点等。示例如下:

import React, { Component } from 'react';

class NoControl extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.setElement = this.setElement.bind(this);
this.myInput = null;
} handleSubmit(e) {
e.preventDefault();
this.forceUpdate();
} setElement(element) {
this.myInput = element;
} componentDidMount() {
this.myInput.focus();
} render() {
return(
<form onSubmit={this.handleSubmit}>
<input type="text" ref={this.setElement}/>
<button type="submit">Submit</button>
</form>
);
}
} export default NoControl;

refs转发

在使用HOC(高阶组件)的时候,我们是用一个类组件来对普通组件进行封装的,这个时候怎么获得里面这个普通组件的ref呢。

react官方提供了React.forwardRef这个api来实现。示例如下:

//NoControl.jsx
import React, { Component } from 'react';
import CustomInput from './CustomInput'; class NoControl extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.myRef = React.createRef();
}
handleSubmit(e) {
e.preventDefault();
this.myRef.current.handleFocus();
this.forceUpdate();
} render() {
return(
<form onSubmit={this.handleSubmit}>
<CustomInput ref={this.myRef}/>
<button type="submit">Submit</button>
</form>
);
}
} export default NoControl; //CustomInput.jsx
import React, { Component } from 'react'; function logProps(Component) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps);
console.log('new props:', this.props);
}
render() {
console.log('HOC exists;');
const { forwardedRef, ...rest } = this.props;
return <Component ref={forwardedRef} {...rest} />;
}
}
function forwardRef(props, ref) {
return <LogProps {...props} forwardedRef={ref} />;
}
return React.forwardRef(forwardRef);
} class CustomInput extends Component {
constructor(props) {
super(props);
this.handleFocus = this.handleFocus.bind(this);
this.myRef = React.createRef();
} handleFocus(e) {
this.myRef.current.focus();
}
render() {
return(
<input type="text" ref={this.myRef}/>
);
}
} export default logProps(CustomInput);

需要注意的是,forwardRef有第二个参数ref,然后它被React.forwardRef这个api封装,最后返回Component类组件。

react中的refs的更多相关文章

  1. React 中的 refs的应用

    React Refs React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上. 这个特殊的属性允许你引用 render() 返回的相应的支撑实例( back ...

  2. 【React】282- 在 React 组件中使用 Refs 指南

    英文:Yomi Eluwande  译文:joking_zhang https://segmentfault.com/a/1190000019277029 使用 React 时,我们的默认思维方式应该 ...

  3. 在 React 组件中使用 Refs 指南

    原文:Fullstack React's Guide to using Refs in React Components作者:Yomi Eluwande译者:博轩 译文:https://segment ...

  4. react中input自动聚焦问题

    input自动聚焦问题 在react中可以使用refs解决这个问题,首先看一下refs的使用场景: (1)处理焦点.文本选择或媒体控制. (2)触发强制动画. (3)集成第三方 DOM 库. 使用re ...

  5. 九、React中的组件、父子组件、React props父组件给子组件传值、子组件给父组件传值、父组件中通过refs获取子组件属性和方法

    一.概述 React中的组件: 解决html 标签构建应用的不足. 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入. [父子组件]:组件的相互调用中,我们把调用者称为父 ...

  6. react中这些细节你注意过没有?

    react中的一些细节知识点: 1.组件中get的使用(作为类的getter) ES6知识:class类也有自己的getter和setter,写法如下: Class Component { const ...

  7. React中ref的使用方法

    React中ref的使用方法 在react典型的数据流中,props传递是父子组件交互的唯一方式:通过传递一个新的props值来使子组件重新re-render,从而达到父子组件通信.当然,就像reac ...

  8. React中setState学习总结

    react中setState方法到底是异步还是同步,其实这个是分在什么条件下是异步或者同步. 1.先来回顾一下react组件中改变state的几种方式: import React, { Compone ...

  9. react中父组件给子组件传值

    子组件 state = { msg: 'a' } render(){ return<h1>{this.state.msg}</h1> } setInfo = (val)=> ...

随机推荐

  1. django 富文本编辑器

    创建工程,数据中数据格式设置为 models.TextField() 此时编辑器是普通的文本框. 使用 tinymce .安装 django-tinymce pip install django-ti ...

  2. 通过PHP调用微信JSSDK实例

    JSSDK使用步骤: 1. 先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”. 2. 采用http GET方式请求获得access_token(有效期7200秒). 3. ...

  3. java中的 java.util.concurrent.locks.ReentrantLock类中的lockInterruptibly()方法介绍

    在java的 java.util.concurrent.locks包中,ReentrantLock类实现了lock接口,lock接口用于加锁和解锁限制,加锁后必须释放锁,其他的线程才能进入到里面执行, ...

  4. Koa源码分析(一) -- generator

    Abstract 本系列是关于Koa框架的文章,目前关注版本是Koa v1.主要分为以下几个方面: 1. Koa源码分析(一) -- generator 2. Koa源码分析(二) -- co的实现 ...

  5. session实现原理(阿里面试题)

    问: 当用户登录某网站后,向服务器发送一个请求,服务器如何判断是这个用户请求的 首先,你要明白一点,最初http协议在设计的时候,主要面向当时的web1.0网站,他们不需要知道是谁来访问,只需要向外界 ...

  6. canvas画布如何画图案例

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  7. 别人的Linux私房菜(14)Linux账号管理和ACL权限设置

    用户标识符UID.GID 用户的账号信息,主要是指UID对应.组和GID对应 检查系统中是否存在用户bin:id bin 登录shell验证账号密码的步骤:找到/etc/passwd核对是否存在账号, ...

  8. SAS 函数

    SAS 函数 SAS函数是编程语言的一个组件,可接受参数.执行计算或进行其他操作并返回值.返回值是字符型或数值型的结果,可用于赋值语句或 表达式中.SAS包含很多函数,也可以自定义函数.在BASE S ...

  9. beego笔记

    beego学习笔记一:创建第一个beego Web项目 Go语言beego框架快速搭建体验五分钟讲解01 beego框架图文简介五分钟讲解02 beego框架图文简介五分钟讲解03-go语言简单方式操 ...

  10. 摘录<奇特的一生>1~4——[苏]格拉宁

    一 只有在不实事求是的时候,事实才会叫人感兴趣. 虚构的人物任人摆布,并且纤毫毕露--他的一切想法意图,他的过去和未来,作者都一清二楚. 我还有一个任务:向读者灌输一些有用的知识,介绍些材料. 是一个 ...