Refs是什么
React 中的 Refs 提供了一种方式,用于访问 render 方法创建的 React元素 或 Dom节点。
本质是返回 ReactDOM.render() 返回的组件实例,如果是渲染组件则返回的是组件实例,如果渲染 dom 则返回的是具体的dom节点。
使用Refs
dom元素使用ref
1、class类组件中的dom元素绑定ref
export default class ClassRef extends React.Component{
constructor(props) {
super(props)
// 创建Refs
this.myRef = React.createRef();
}
clickButton = () =>{
// 访问Refs
console.log('this.ref',this.myRef)
this.myRef.current.value = 'ddsds';
}
render(){
return (
<div>
<button onClick={this.clickButton}>ref点击</button>
// 绑定Refs,1
test:<input type="text" ref={this.myRef} />
// 绑定Refs,2
<input type="text" ref={(element)=>{ this.myRef = element}} />
</div>
)
}
}
由上能发现 this.myRef.current 拿到了整个 input 节点,点击时可以如上更新input的value值
第二种绑定方法,this.myRef 直接拿到了node节点
2、hook组件中的dom元素绑定ref
import React,{ useRef } from 'react';
function HookRef() {
// 创建Refs
const myRef = useRef(null)
function refClick(){
// 访问Refs
console.log('myRef',myRef);
myRef.current.focus();
}
return (
<div>
// 绑定Refs
<input ref={ myRef } type="text"/>
<button onClick={ refClick }>ref click</button>
</div>
);
}
myRef.current 拿到的值跟上面class的是一至的,调用foucs() 方法时,input获得焦点光标选中。
组件使用ref
1、class组件使用ref
import React from "react";
import ClassSelfR from "../ClassSelf";
export default class ClassRef extends React.Component{
constructor(props) {
super(props)
// 创建Refs
this.myRef = React.createRef();
}
clickButton = () =>{
// 访问Refs
console.log('this.ref',this.myRef)
this.myRef.current.setState({tag:'hah'})
}
render(){
return (
<div>
<button onClick={this.clickButton}>ref点击</button>
// 绑定Refs
<ClassSelfR ref={this.myRef}/>
</div>
)
}
}
class ClassSelfR extends React.Component {
constructor (props){
super(props)
this.aa = 99
this.state = {
tag:'wq'
}
}
a = 9
render(){
return <div>{this.state.tag}</div>
}
}
可以看到,拿到了整个子组件ClassSelfR 的实例,且可以调用 setState 改变tag值
2、函数组件不能使用ref
export default class ClassRef extends React.Component{
constructor(props) {
super(props)
this.myRef = React.createRef();
}
clickButton = () =>{
console.log('this.ref',this.myRef)
}
render(){
return (
<div>
// This will *not* work!
<button onClick={this.clickButton}>ref点击</button>
<HookT ref= {this.myRef} />
</div>
)
}
}
function HookT() {
return <input />;
}
不正当使用Refs
将子组件dom通过ref暴露给父组件
1、Refs转发
export default class ClassRef extends React.Component{
constructor(props) {
super(props)
this.myRef = React.createRef();
}
clickButton = () =>{
console.log('this.ref',this.myRef)
}
render(){
return (
<div>
<button onClick={this.clickButton}>ref点击</button>
<HookRef ref= {this.myRef} > 点击</HookRef>
</div>
)
}
}
const HookRef = React.forwardRef((props, ref)=>{
return(
<button ref={ref}>
{ props.children }
</button>
)
})
ref转发允许某些组件接收 ref,并向下传递给子组件。第二个参数 ref 只在使用 React.forwardRef 定义组件时存在。常规函数和 class 组件不接收 ref 参数,且 props 中也不存在 ref。
Ref 转发不仅限于 DOM 组件,你也可以转发 refs 到 class 组件实例中。
2、回调Refs
export default class ClassRef extends React.Component{
constructor(props) {
super(props)
this.myRef = React.createRef();
}
clickButton = () =>{
console.log('this.ref',this.myRef)
this.myRef.value = 99
}
render(){
return (
<div>
<button onClick={this.clickButton}>ref点击</button>
// 回调函数 当成props 传递给子组件
<HookT inRef={ element => this.myRef = element}></HookT>
</div>
)
}
}
function HookT( props) {
return (
<div>
<input ref={props.inRef} type="text"/>
</div>
);
}
点击时可以直接取到子组件的dom,并且改变了它的value值
将父组件某个dom通过ref暴露给子组件
export default class ClassRef extends React.Component{
constructor(props) {
super(props)
this.myRef = React.createRef();
}
render(){
return (
<div>
test:<input type="text" ref={this.myRef} />
<HookT inRef= {this.myRef}></HookT>
</div>
)
}
}
function HookT( props) {
return (
<div>
<button onClick={()=>{
console.log('this.ref',props.inRef);
props.inRef.current.value =99}
}>
click
</button>
</div>
);
}
把ref当成参数传过去,子组件可以获得父组件里的dom。嗯,可以但没必要没啥用