react中的refs
概述
很久之前就知道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属性,它的值取决于下面三种情况:
- 如果ref属性被用于html元素,那么它的值是底层DOM元素。
- 如果ref属性被用于自定义类组件,那么它的值是已挂载的这个自定义类组件的实例。
- 函数式组件没有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的更多相关文章
- React 中的 refs的应用
React Refs React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上. 这个特殊的属性允许你引用 render() 返回的相应的支撑实例( back ...
- 【React】282- 在 React 组件中使用 Refs 指南
英文:Yomi Eluwande 译文:joking_zhang https://segmentfault.com/a/1190000019277029 使用 React 时,我们的默认思维方式应该 ...
- 在 React 组件中使用 Refs 指南
原文:Fullstack React's Guide to using Refs in React Components作者:Yomi Eluwande译者:博轩 译文:https://segment ...
- react中input自动聚焦问题
input自动聚焦问题 在react中可以使用refs解决这个问题,首先看一下refs的使用场景: (1)处理焦点.文本选择或媒体控制. (2)触发强制动画. (3)集成第三方 DOM 库. 使用re ...
- 九、React中的组件、父子组件、React props父组件给子组件传值、子组件给父组件传值、父组件中通过refs获取子组件属性和方法
一.概述 React中的组件: 解决html 标签构建应用的不足. 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入. [父子组件]:组件的相互调用中,我们把调用者称为父 ...
- react中这些细节你注意过没有?
react中的一些细节知识点: 1.组件中get的使用(作为类的getter) ES6知识:class类也有自己的getter和setter,写法如下: Class Component { const ...
- React中ref的使用方法
React中ref的使用方法 在react典型的数据流中,props传递是父子组件交互的唯一方式:通过传递一个新的props值来使子组件重新re-render,从而达到父子组件通信.当然,就像reac ...
- React中setState学习总结
react中setState方法到底是异步还是同步,其实这个是分在什么条件下是异步或者同步. 1.先来回顾一下react组件中改变state的几种方式: import React, { Compone ...
- react中父组件给子组件传值
子组件 state = { msg: 'a' } render(){ return<h1>{this.state.msg}</h1> } setInfo = (val)=> ...
随机推荐
- JAVA多线程之线程间的通信方式
(转发) 收藏 记 周日,北京的天阳光明媚,9月,北京的秋格外肃穆透彻,望望窗外的湛蓝的天,心似透过栏杆,沐浴在这透亮清澈的蓝天里,那朵朵白云如同一朵棉絮,心意畅想....思绪外扬, 鱼和熊掌不可兼得 ...
- Unity3D-RayMarch-几何图元0
效果图: 将下面的shader代码对应的Material拖给一个面片,即可看到效果. shader代码: // Upgrade NOTE: replaced '_Object2World' with ...
- Android自动化之Monkey环境搭建(一)
从事测试行业两年了,一直很喜欢研究新技术,但是最近有点慵懒.正好公司新出了产品,督促我学习monkey用来测其稳定性. 网上搜索了很久,内容总是很零散,通常需要找几篇文章才能搭好环境.特写此文,一篇文 ...
- hbase_基本命令
hbase 区分大小写. 1) create '表名','列族名' --多个列族名用逗号分隔 2) list desc(查询表名详细信息) 3) put '表名','行健','列族:列名',' ...
- SHELL脚本学习-自动生成AWR报告
自动生成AWR报告,每个小时生成一次. #编辑脚本:vim awr_auto.sh #oracle用户下执行 #!/bin/bash # 每个小时执行一次,自动生成AWR报告 source ~/.ba ...
- PHP爬虫百度图片
php pacong_1.php "酒","电报","电表","电波","电厂","电场& ...
- 【机器学习】K均值算法(I)
K均值算法是一类非监督学习类,其可以通过观察样本的离散性来对样本进行分类. 例如,在对如下图所示的样本中进行聚类,则执行如下步骤 1:随机选取3个点作为聚类中心. 2:簇分配:遍历所有样本然后依据每个 ...
- 重置表单中的文件上传控件(file input)的方法
方法一: 调用所在 form 表单的 reset 方法,这个方法的缺点是会把整个表单重置,需要存储表单的状态,再回填回去 方法二: 使用jQuery,代码为: $("#id").r ...
- UWP作业(二)A Mobile App
看到给出的十个技术主题,我第一反应就是,对于大部分社交软件来讲,运用到全部这些都并不是什么难题,倒不如谈谈我手机里现有的社交软件中,使用时间最短但(you)是(dian)最(bu)好(hao)奇(yo ...
- ThinkPHP 3.2.3+ORACLE插入数据BUG修复及支持获取自增Id的上次记录
TP+ORACLE插入数据BUG修复以及获取自增Id支持getLastInsID方法 这些天在做Api接口时候,发现用TP操作Oracle数据库,发现查询修改删除都能执行, 但一旦执行插入操作老是报错 ...