React 中需要操作元素时,可通过 findDOMNode() 或通过 createRef() 创建对元素的引用来实现。前者官方不推荐,所以这里讨论后者及其与 TypeScript 结合时如何工作。

React 中的元素引用

正常的组件中,可通过创建对元素的引用来获取到某元素然后进行相应操作。比如元素加载后将焦点定位到输入框。

class App extends Component {
constructor(props){
super(props);
this.inputRef = React.createRef();
} componentDidMount(){

this.inputRef.current.focus()

} render() {

return (

<div className="App">

<input type="text" ref={this.inputRef}/>

</div>

);

}

}

创建对元素的引用是通过 React.createRef() 方法完成的。使用的时候,通过其返回对象身上的 current 属性可访问到绑定引用的元素。

React 内部对引用的 current 赋值更新发生在 componentDidMountcomponentDidUpdate 生命周期之前,即存在使用的时候引用未初始化完成的情况,所以 current 不一定有值。好的做法是使用前先判空。

if(this.inputRef.current){
this.inputRef.current.focus()
}

在上面的示例中,之所以不用判空是因为我们在 componentDidMount 生命周期中使用,此时元素已经加载到页面,所以可以放心使用。

组件中引用的传递

对于原生 DOM 元素可以像上面那样创建引用,但对于自己写的组件,则需要使用 forwardRef() 来实现。

假如你写了个按钮组件,想要实现像上面那样,让使用者可通过传递一个 ref 属性来获取到组件中原生的这个 <button> 元素以进行相应的操作。

button.jsx

const FancyInput = props => <input type="text" className="fancy-input" />;

添加 ref 支持后的按钮组件:

button.jsx

const FancyInput = React.forwardRef((props, ref) => {
return <input type="text" ref={ref} className="fancy-input" />;
});

forwardRef 接收一个函数,函数的入参中第一个是组件的 props,第二个便是外部传递进来的 ref 引用。通过将这个引用在组件中绑定到相应的原生 DOM 元素上,实现了外部直接引用到组件内部元素的目的,所以叫 forwardRef(传递引用)。

使用上面创建的 FancyInput,在组件加载后使其获得焦点:

class App extends Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
} componentDidMount() {

if (this.inputRef.current) {

this.inputRef.current.focus();

}

} render() {

return (

<div className="App">

- <input type="text" ref={this.inputRef}/>

+ <FancyInput ref={this.inputRef} />

</div>

);

}

}

TypeScript 中传递引用

先看正常情况下,对原生 DOM 元素的引用。还是上面的示例:

class App extends Component<{}, {}> {
private inputRef = React.createRef(); componentDidMount() {

/**

最新文章

  1. [LeetCode] Ransom Note 赎金条
  2. UVALive 4428 Solar Eclipse --计算几何,圆相交
  3. github安装&amp;初探
  4. HTML中强大的input标签属性
  5. nice
  6. hdu1171
  7. wordpress忘记密码重置
  8. 《C和指针》章节后编程练习解答参考——第10章
  9. android使用属性动画代替补间动画
  10. linux之cal命令
  11. ajax封装
  12. C语言入门(9)——局部变量与全局变量
  13. php面试问题
  14. 一个基于ES6+webpack的vue小demo
  15. [转] 分享一个快的飞起的maven的settings.xml文件
  16. Zabbix 3.4.7调整监控阈值以及告警级别
  17. Unable to determine the device handle for GPU 0000:01:00.0: GPU is lost.问题排坑
  18. MOBA英雄AI设计分享
  19. (转)CS0016: 未能写入输出文件
  20. Android.mk (2) 函数进阶教程 - 分支、循环、子程序

热门文章

  1. python爬虫入门(二)Opener和Requests
  2. This 在构造函数中的固定用法
  3. linux 文件传输 SCP
  4. Python_将指定文件夹中的文件压缩至已有压缩包
  5. Spring中的循环依赖
  6. 并发库应用之八 &amp; 循环路障CyclicBarrier应用
  7. capwap学习笔记——初识capwap(二)(转)
  8. UIDatePicker在swift中的使用
  9. Mysql 30条军规
  10. Linux kernel的中断子系统之(五):驱动申请中断API