什么是Refs
Refs 提供了一种方式,允许我们访问 DOM 节点或在 render 方法中创建的 React 元素。
Ref转发是一项将ref自动通过组件传递到子组件的技巧。 通常用来获取DOM节点或者React元素实例的工具。在React中Refs提供了一种方式,允许用户访问dom节点或者在render方法中创建的React元素。
Refs转发
Ref 转发是一个可选特性,其允许某些组件接收 ref,并将其向下传递(换句话说,“转发”它)给子组件。
默认情况下,不能在函数组件上使用 ref 属性,因为它们没有实例:
一、String 类型的 Refs
不建议使用,因为 string 类型的 refs 存在一些问题。它已过时并可能会在未来的版本被移除。
import React from "react";
// 父组件
export default class StringRef extends React.PureComponent {
componentDidMount() {
console.log("stringRefDom:", this.refs.stringRefDom);
console.log("stringRefComp:", this.refs.stringRefComp);
}
render() {
return (
<div>
{}
<div ref={"stringRefDom"}>stringRefDom</div>
{}
<StringRefComp ref={"stringRefComp"} />
</div>
);
}
}
//类组件
class StringRefComp extends React.PureComponent {
render() {
return <div>StringRefComp</div>;
}
}
二、回调 Refs
- 如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次
- 第一次传入参数 null,然后第二次会传入参数 DOM 元素
- 这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的
- 通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题
- 但是大多数情况下它是无关紧要的
import React from "react";
// 父组件
export default class CallbackRef extends React.PureComponent {
constructor(props) {
super(props);
this.callbackRefDom = null;
this.callbackRefComp = null;
}
componentDidMount() {
console.log("callbackRefDom:", this.callbackRefDom);
console.log("callbackRefComp:", this.callbackRefComp);
}
//回调函数
setCallbackRefDom = (ref) => {
this.callbackRefDom = ref;
};
setCallbackRefComp = (ref) => {
this.callbackRefComp = ref;
};
//回调函数
render() {
return (
<div>
<div ref={this.setCallbackRefDom}>callbackRefDom</div>
<CallbackRefComp ref={this.setCallbackRefComp} />
</div>
);
}
}
//类组件
class CallbackRefComp extends React.PureComponent {
render() {
return <div>callbackRefComp</div>;
}
}
三、React.createRef()
- React 16.3 版本引入
- 较早版本的 React,推荐使用回调形式的 refs
import React from "react";
// 父组件
export default class CreateRef extends React.PureComponent {
constructor(props) {
super(props);
this.createRefDom = React.createRef();
this.createRefComp = React.createRef();
}
componentDidMount() {
console.log("createRefDom:", this.createRefDom.current);
console.log("createRefComp:", this.createRefComp.current);
}
render() {
return (
<div>
<div ref={this.createRefDom}>createRefDom</div>
<CreateRefComp ref={this.createRefComp} />
</div>
);
}
}
//类组件
class CreateRefComp extends React.PureComponent {
render() {
return <div>CreateRefComp</div>;
}
}
四、useRef
- Hook 是 React 16.8 的新增特性
import React, { useEffect } from "react";
// 父组件
const UseRef = React.memo(() => {
// // 同样可以用
// const createRefDom = React.createRef();
// const createRefComp = React.createRef();
const createRefDom = React.useRef();
const createRefComp = React.useRef();
useEffect(() => {
console.log("useRefDom:", createRefDom.current);
console.log("useRefComp:", createRefComp.current);
}, []);
return (
<div>
<div ref={createRefDom}>useRefDom</div>
<UseRefComp ref={createRefComp} />
</div>
);
});
export default UseRef;
//类组件
class UseRefComp extends React.PureComponent {
render() {
return <div>useRefComp</div>;
}
}
五、Refs 与函数组件
- 默认情况下,你不能在函数组件上使用 ref 属性,因为它们没有实例
- 如果要在函数组件中使用 ref,你可以使用 forwardRef(可与 useImperativeHandle 结合使用)
- 或者将该组件转化为 class 组件。
import React, { useEffect, useImperativeHandle } from "react";
// 父组件
const ForwardRef = React.memo(() => {
const createRefComp = React.useRef();
const createRefCompMethod = React.useRef();
useEffect(() => {
console.log("useRefComp:", createRefComp.current);
console.log("createRefCompMethod:", createRefCompMethod.current);
createRefComp.current.reload();
}, []);
return (
<div>
<ForwardRefFunc ref={createRefComp} />
</div>
);
});
export default ForwardRef;
const RefFunc = React.forwardRef((props, ref) => {
const [name, setName] = React.useState(null);
const reload = () => {
console.log("reload");
setTimeout(() => {
setName("ForwardRefFunc");
}, 3000);
};
//useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值
useImperativeHandle(ref, () => {
return {
reload: reload,
};
});
return <div ref={ref}>ForwardRefFunc {name}</div>;
});
const ForwardRefFunc = React.memo(RefFunc);
forwardRef 和 useImperativeHandle 最终目的是设法给 ref 提供一个可调用的对象!
- Refs and the DOM
- forwardRef
- useimperativehandle
总结
到此这篇关于React中refs的一些常见用法的文章就介绍到这了,更多相关React中refs用法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!