在react典型的数据流中,props传递是父子组件交互的一种方式;通过传递一个新的props值来使子组件重新render,从而达到父子组件通信。某些情况下(例如和第三方的dom库整合,或者某个dom元素focus等)为了修改子组件我们可能需要另一种方式,这就是ref方式。

React提供的这个ref属性,表示为对组件真正实例的引用,其实就是ReactDOM.render()返回的组件实例;需要区分一下,ReactDOM.render()渲染组件时返回的是组件实例;而渲染dom元素时,返回是具体的dom节点。

1. react ref

state = {inputVisible: false,inputValue: '',
};
render() {const { inputVisible, inputValue } = this.state;return ({inputVisible?(<Inputref={input=>{this.input = input;}}value={inputValue}onChange={e=>{this.setState({ inputValue: e.target.value });}}/>):(<Tag onClick={()=>{this.setState({ inputVisible: true }, () => this.input.focus());}}><PlusOutlined /> New Tag</Tag>)})
}
// 父组件
import { PureComponent } from 'react';
import Children from './Children';
export default class Parent extends PureComponent {constructor() {super();this.state = {}}getChildren(){console.log(this.childrenRef)}render(){return (<div><div onClick={()=>this.getChildren()}></div><Children onRef={(ref)=>(this.childrenRef = ref)}/></div>);}
}// 子组件
import { PureComponent } from 'react';
export default class Children extends PureComponent {constructor() {super();this.state = {name: 'Children'}}componentDidMount() {this.props.onRef(this)}render(){return (<div>{this.state.name}</div>);}
}

https://www.cnblogs.com/wonyun/p/6395849.html

2. hook ref

import { useState, useEffect, useRef }  from 'react';const inputRef = useRef(null)const [inputVisible,setInputVisible] = useState<boolean>(false);
const [inputValue,setInputValue] = useState<string>('');useEffect(() => {inputVisible && inputRef.current.focus()
},[inputVisible]);return ({inputVisible?(<Inputref={inputRef}value={inputValue}onChange={(e)=>setInputValue(e.target.value)}/>):(<Tag onClick={()=>{setInputVisible(true);}}><PlusOutlined /> New Tag</Tag>)}
)

3. 比较

  • react

    // 定义ref
    ref={(ref) => {this.inputRef= ref
    }}
    // 使用ref
    this.inputRef.focus()
    
  • react hook
    // 声明ref
    const inputRef= useRef()
    // 复值给组件
    ref={inputRef}
    // 使用ref
    inputRef.current.focus()
    

4. 问题解决

为什么useRef Hook的.current为空

Ref.current 为空,因为只有在函数返回并呈现内容之后才设置ref。每当传递给useffect钩子的数组的内容值发生更改时,它都会触发useffect钩子。通过在数组中传递 observed 并将记录 observed 的回调传递到控制台,可以利用useffect钩子来完成任务。

useEffect(() => {console.log(inputRef.current);
}, [inputVisible]);

Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

export default connect(( {user,api} ) => ({currentUser: user.currentUser , api
}), null, null, { forwardRef: true })(Children);

ref使用之react / react hook相关推荐

  1. 【笔记-node】《Egg.js框架入门与实战》、《用 React+React Hook+Egg 造轮子 全栈开发旅游电商应用》

    20210226-20210227:<Egg.js框架入门与实战> 课程地址:https://www.imooc.com/learn/1185 第一章 课程导学 01-01 课程介绍 一. ...

  2. React全Hook项目实战在线聊天室历程(三):加个音乐直播?

    前情提要: React全Hook项目实战在线聊天室历程(一):基本功能 React全Hook项目实战在线聊天室历程(二):引用与话题功能 正文 聊天应该有什么?背景音乐,茶与酒,零食,后两个我是没法实 ...

  3. react中ref、createRef、React.forwardRef分别是什么?如何使用?

    一.react中ref.createRef.React.forwardRef (1)Ref 转发是一项将 ref 自动地通过组件传递到其一子组件的技巧.对于大多数应用中的组件来说,这通常不是必需的.但 ...

  4. [react] react中可以在render访问refs吗?为什么?

    [react] react中可以在render访问refs吗?为什么? <><span id="name" ref={this.spanRef}>{this ...

  5. [react] react组件间的通信有哪些?

    [react] react组件间的通信有哪些? Props Context ref:通过Ref获取组建的实例,在通过实例拿到组件的属性值或者方法的回调 第三方的,Redux是基于Conext基础上的库 ...

  6. [react] react怎么拿到组件对应的DOM元素?

    [react] react怎么拿到组件对应的DOM元素? 在Class组件中 import React from 'react'; class CComponent extends React.Com ...

  7. [react] react中什么是非控组件?

    [react] react中什么是非控组件? 表单元素的value/checked值.onChange事件没有和组件的state存在绑定关联关系,如果需要获取表单元素的值,需要使用ref获取DOM,然 ...

  8. [react] React中怎么操作虚拟DOM的Class属性

    [react] React中怎么操作虚拟DOM的Class属性 render() { this.debug('render ....'); this.components.push(<Atten ...

  9. [react] React为什么要搞一个Hooks?

    [react] React为什么要搞一个Hooks? 动机 Hook 解决了我们五年来编写和维护成千上万的组件时遇到的各种各样看起来不相关的问题.无论你正在学习 React,或每天使用,或者更愿尝试另 ...

最新文章

  1. 【c语言】蓝桥杯算法提高 选最大数
  2. 公司的实战Replica Sets+Sharding方案
  3. 【Python】Django生成API 文档
  4. Python属性访问拦截器的用法
  5. java怎么获取文本里的值_怎么获取到text中的文本,或者title中的值
  6. xml 转map dom4j
  7. 简单版:带干扰线的图形验证码生成
  8. 大厂程序员辞职创业,赚的还没原来多!
  9. 用于角点检测的FAST算法
  10. 桌面环境选择_如何在 Ubuntu 20.04 LTS 上安装深度(Deepin)桌面环境 | Linux 中国
  11. TUIO之TuioDemo
  12. 计算机上怎么在表格输入分秒,“excel表格怎么输入角度“excel 表格中怎么输入分秒的符号...
  13. 学校机房计算机类型,学校计算机机房的管理和维护建议原稿(备份存档)
  14. java 正则拼音_正则匹配拼音
  15. python中chr()和ord()函数的用法
  16. 微信投票的自动运行脚本
  17. Qt与Mysql进行连接实现账号的注册登录和密码修改和验证码
  18. dbv数据库乱码_使用DBV进行数据库版本控制
  19. 职场002:什么是可迁移能力
  20. 旭锋科技制造信息管理系统

热门文章

  1. 什么是jsf_什么是JSF? JavaServer Faces简介
  2. 生成有feature的pattern-graph数据集
  3. C#中Atan()与Atan2()
  4. Django项目中浏览器显示127.0.0.1拒绝我们的连接请求
  5. sd3403开发板学习(一)
  6. [Win32] 获取进程完整路径
  7. 高中科幻作文关于计算机,高中科幻作文(精选5篇)
  8. NBD Network Block Device
  9. 自动创建 api 模拟数据
  10. Progress ThemeBuilder updated Crack