ref
记忆功能(与 useState 区别)
获取 dom
组件 ref
暴露出组件方法
警告
useRef 不触发渲染
useRef 必须得用 current 来获取值
记忆功能
- 不触发渲染
举例子
- 这种情况下 它清除不了最开始的 timer,而是自己又新开了一个
js
import React, { useRef } from "react";
import Son from "./Son";
function App() {
let timer = null;
const handleClick = () => {
clearInterval(timer);
timer = setInterval(() => {
console.log("hello");
}, 1000);
};
return (
<div>
<h1 onClick={handleClick}>定时器</h1>
<Son></Son>
</div>
);
}
export default App;
解决这个问题
- 使用 useRef 来解决
js
import React, { useRef } from "react";
import Son from "./Son";
function App() {
let timer = useRef(null);
const handleClick = () => {
clearInterval(timer.current);
timer.current = setInterval(() => {
console.log("hello");
}, 1000);
};
return (
<div>
<h1 onClick={handleClick}>定时器</h1>
<Son></Son>
</div>
);
}
export default App;
获取 dom
- 获取 dom 改变文字颜色
js
import React, { useRef } from "react";
import Son from "./Son";
function App() {
const h1dom = useRef(null);
const handleClick = () => {
h1dom.current.style.color = "red";
};
return (
<div>
<h1 onClick={handleClick} ref={h1dom}>
定时器
</h1>
<Son></Son>
</div>
);
}
export default App;
组件 ref
给组件绑定 ref
forwardRef 包裹组件
通过 ref 指定元素
父元素
js
import React, { useRef } from "react";
import Son from "./Son";
function App() {
const h1dom = useRef(null);
const handleClick = () => {
console.log(h1dom.current); // 就能获取到 <h1>son</h1
};
return (
<div>
<h1 onClick={handleClick}>获取dom</h1>
<Son ref={h1dom}></Son>
</div>
);
}
export default App;
子元素
- Son 括号里面不用
{}
直接就是 props,ref
- Son 括号里面不用
- forwardRef 包裹组件
- 通过 ref 指定元素
js
import React, { forwardRef } from "react";
function Son(props, ref) {
console.log("子元素渲染");
return (
<div>
<h1 ref={ref}> Son</h1>
</div>
);
}
export default forwardRef(Son);
暴露出组件的方法
Son 还是得括号里写 props,ref
useImperativeHandle 指定 ref 暴露的方法或者属性,必须 return
通过 ref 暴露出我想指定的方法
子元素
js
import React, { forwardRef, useImperativeHandle } from "react";
function Son(props, ref) {
// 指定暴露的方法
useImperativeHandle(ref, () => {
return {
fn1() {
console.log("子组件暴露的方法1");
},
fn2() {
console.log("子组件暴露的方法2");
},
};
});
return (
<div>
<h1> Son</h1>
</div>
);
}
export default forwardRef(Son);
父元素
js
import React, { useRef } from "react";
import Son from "./Son";
function App() {
const h1dom = useRef(null);
const handleClick = () => {
console.log(h1dom.current);
h1dom.current.fn1();
h1dom.current.fn2();
};
return (
<div>
<h1 onClick={handleClick}>获取dom</h1>
<Son ref={h1dom}></Son>
</div>
);
}
export default App;