Dom上的ref
refs 提供了一种方式,允许我们访问 DOM 节点,可以对dom进行操作
注意:ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素作为其 current 属性
import React from "react";
class RefDomClass extends React.Component {
constructor(props) {
super(props);
this.InputRef = React.createRef();
}
componentDidMount() {
this.InputRef.current.value = "赋值";
}
render() {
return (
<div>
<h3>RefDomClass</h3>
<input ref={this.InputRef} />
</div>
);
}
}
export default RefDomClass;
类组件的ref
在类组件上使用ref,可以通过ref获取类组件的实例,从而可以调用类组件的方法和获取state等
注意:当 ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性
//app.js
import React from "react";
import RefClassComponents from "./RefClassComponents";
export default function App() {
let refClassComponents;
function getRefClassComponents(ref) {
//返回类组件的实例
refClassComponents = ref;
}
function addCount() {
refClassComponents.addCount();
}
return (
<div className="App">
<div>
<RefClassComponents ref={getRefClassComponents} />
<button onClick={addCount}>add count</button>
</div>
</div>
);
}
//RefClassComponents
import React from "react";
class RefClassComponents extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 1
};
this.addCount.bind(this);
}
addCount() {
this.setState(({ count }) => {
return {
count: ++count
};
});
}
render() {
const { count } = this.state;
return (
<div>
<h3>RefClassComponents</h3>
<div>count {count}</div>
</div>
);
}
}
export default RefClassComponents;
函数组件 useRef
useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变
注意:ref的对象如果没有绑定在dom上,current为初始化传入的对象,如果绑定了dom就是dom的实例
import { useRef } from "react";
function UseRef() {
const inputRef = useRef();
function changeText() {
inputRef.current.value = "changed";
}
return (
<div>
<h3>UseRef</h3>
<input ref={inputRef} />
<button onClick={changeText}>change</button>
</div>
);
}
export default UseRef;
forwardRef和useImperativeHandle
React.forwardRef 会创建一个React组件,这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中。
import { useState, forwardRef, useImperativeHandle } from "react";
const RefFunctionComponents = forwardRef((props, ref) => {
let [count, setCount] = useState(0);
function setCountClick() {
setCount(++count);
}
useImperativeHandle(ref, () => ({
addCount: () => {
setCountClick();
}
}));
return (
<div>
<div>
<h3>RefFunctionComponents</h3>
<div>count {count}</div>
{/* <button onClick={setCountClick}>add count </button> */}
</div>
</div>
);
});
export default RefFunctionComponents;
效果如下